From 00dcc07877ca1d10ce9a5b3c7206b3b612e3feba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Thu, 11 Oct 2018 21:19:28 +0200 Subject: [PATCH 1/7] Update Copyright notice for my fork. --- COPYING | 2 ++ 1 file changed, 2 insertions(+) diff --git a/COPYING b/COPYING index 6443794..59fba4f 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,6 @@ Copyright 2018 Prodrive Technologies B.V. +Copyright 2018 Google LLC. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at From c5b4d8188805ba5a5ac6a76a461c49c6b592ee2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Thu, 11 Oct 2018 22:55:07 +0200 Subject: [PATCH 2/7] Make output declaration mandatory in pandoc rule It's important that users of the rule can change the output. See #1 * Make "output": attr.output(mandatory = True), * Change the output of the sample generation to "readme_format.format" --- BUILD.bazel | 2 ++ pandoc.bzl | 26 ++++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 84fee44..0a96f0a 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -42,6 +42,8 @@ pandoc_toolchain( src = "README.md", from_format = "markdown", to_format = fmt, + # TODO(regisd) Infer extension from to_format + output = "readme_" + fmt + "." + fmt, ) for fmt in [ "asciidoc", "beamer", diff --git a/pandoc.bzl b/pandoc.bzl index b2e82f2..dc95e5b 100644 --- a/pandoc.bzl +++ b/pandoc.bzl @@ -1,19 +1,21 @@ def _pandoc_impl(ctx): toolchain = ctx.toolchains["@bazel_pandoc//:pandoc_toolchain_type"] + cli_args = [] + cli_args.extend(ctx.attr.options) + if ctx.attr.from_format: + cli_args.extend(["--from", ctx.attr.from_format]) + if ctx.attr.to_format: + cli_args.extend(["--to", ctx.attr.to_format]) + cli_args.extend(["-o", ctx.outputs.output.path]) + cli_args.append(ctx.file.src.path) + + print("args=" + str(cli_args)) ctx.actions.run( mnemonic = "Pandoc", executable = toolchain.pandoc.files.to_list()[0].path, - arguments = ctx.attr.options + [ - "--from", - ctx.attr.from_format, - "--to", - ctx.attr.to_format, - "-o", - ctx.outputs.out.path, - ctx.files.src[0].path, - ], + arguments = cli_args, inputs = toolchain.pandoc.files + ctx.files.src, - outputs = [ctx.outputs.out], + outputs = [ctx.outputs.output], ) _pandoc = rule( @@ -21,10 +23,10 @@ _pandoc = rule( "extension": attr.string(), "from_format": attr.string(), "options": attr.string_list(), - "src": attr.label(allow_files = True), + "src": attr.label(allow_single_file = True, mandatory = True), "to_format": attr.string(), + "output": attr.output(mandatory = True), }, - outputs = {"out": "%{name}.%{extension}"}, toolchains = ["@bazel_pandoc//:pandoc_toolchain_type"], implementation = _pandoc_impl, ) From b1fd792a46bd6962d95d264292c9839387ba64d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Tue, 16 Oct 2018 00:06:29 +0200 Subject: [PATCH 3/7] Comment debug statement --- pandoc.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandoc.bzl b/pandoc.bzl index dc95e5b..5849767 100644 --- a/pandoc.bzl +++ b/pandoc.bzl @@ -9,7 +9,7 @@ def _pandoc_impl(ctx): cli_args.extend(["-o", ctx.outputs.output.path]) cli_args.append(ctx.file.src.path) - print("args=" + str(cli_args)) + # print("args=" + str(cli_args)) ctx.actions.run( mnemonic = "Pandoc", executable = toolchain.pandoc.files.to_list()[0].path, From dd5ce230c3553427cb356058c9145576881e9e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Mon, 2 Dec 2019 01:06:42 +0100 Subject: [PATCH 4/7] Make from_format and to_format optional --- pandoc.bzl | 53 +++++++++++++++++++++++++++++----------------- sample/BUILD.bazel | 15 ++++++++++++- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/pandoc.bzl b/pandoc.bzl index 4b3baa4..d365128 100644 --- a/pandoc.bzl +++ b/pandoc.bzl @@ -48,47 +48,60 @@ PANDOC_EXTENSIONS = { "textile": "textile", "zimwiki": "txt", } +PANDOC_FORMATS = PANDOC_EXTENSIONS.keys() def _pandoc_impl(ctx): toolchain = ctx.toolchains["@bazel_pandoc//:pandoc_toolchain_type"] + cli_args = [] + cli_args.extend(ctx.attr.options) + if ctx.attr.from_format: + cli_args.extend(["--from", ctx.attr.from_format]) + if ctx.attr.to_format: + cli_args.extend(["--to", ctx.attr.to_format]) + cli_args.extend(["-o", ctx.outputs.output.path]) + cli_args.extend([ctx.files.src[0].path]) ctx.actions.run( mnemonic = "Pandoc", executable = toolchain.pandoc.files.to_list()[0].path, - arguments = ctx.attr.options + [ - "--from", - ctx.attr.from_format, - "--to", - ctx.attr.to_format, - "-o", - ctx.outputs.out.path, - ctx.files.src[0].path, - ], + arguments = cli_args, inputs = depset( direct = ctx.files.src, transitive = [toolchain.pandoc.files], ), - outputs = [ctx.outputs.out], + outputs = [ctx.outputs.output], ) _pandoc = rule( attrs = { - "extension": attr.string(), "from_format": attr.string(), "options": attr.string_list(), "src": attr.label(allow_files = True), "to_format": attr.string(), + "output": attr.output(mandatory = True), }, - outputs = {"out": "%{name}.%{extension}"}, toolchains = ["@bazel_pandoc//:pandoc_toolchain_type"], implementation = _pandoc_impl, ) -def pandoc(**kwargs): - # Derive extension of the output file based on the desired format. - # Use the generic .xml syntax for XML-based formats and .txt for - # ones with no commonly used extension. - to_format = kwargs["to_format"] - if to_format not in PANDOC_EXTENSIONS: - fail("Unknown output format: " + to_format) +def _check_format(format, attr_name): + if format not in PANDOC_EXTENSIONS: + fail("Unknown %{attr} format: %{format}".fmt(attr = attr_name, format = format)) + return format + +def _infer_output(name, to_format): + """Derives output file based on the desired format. - _pandoc(extension = PANDOC_EXTENSIONS[to_format], **kwargs) + Use the generic .xml syntax for XML-based formats and .txt for + ones with no commonly used extension. + """ + to_format = _check_format(to_format, "to_format") + ext = PANDOC_EXTENSIONS[to_format] + return name + "." + ext + +def pandoc(**kwargs): + if "from_format" in kwargs: + _check_format(kwargs["from_format"], "from_format") + if "output" not in kwargs: + to_format = _check_format(kwargs["to_format"], "to_format") + kwargs["output"] = _infer_output(kwargs["name"], to_format) + _pandoc(**kwargs) diff --git a/sample/BUILD.bazel b/sample/BUILD.bazel index a9a873c..b4b1f68 100644 --- a/sample/BUILD.bazel +++ b/sample/BUILD.bazel @@ -1,7 +1,20 @@ load("//:pandoc.bzl", "PANDOC_EXTENSIONS", "pandoc") -# Conversion of README to various formats for testing. +# Simplest possible example, where the to_format is specified +pandoc( + name = "readme1", + src = "//:README.md", + to_format = "asciidoc", +) +# Simplest possible example, where the output is specified +pandoc( + name = "readme2", + src = "//:README.md", + output = "readme2.html", +) + +# Conversion of README to various formats for testing. [pandoc( name = "readme_" + fmt, src = "//:README.md", From 278bfea9cb9c608a16d7fcea7b6f2f419f02300a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Mon, 2 Dec 2019 01:40:46 +0100 Subject: [PATCH 5/7] Update documentation --- README.md | 16 ++++++++------ pandoc.bzl | 6 ++--- sample/BUILD.bazel | 22 +++++++------------ sample/README.md | 55 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 74 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 660e3c0..aadf97a 100644 --- a/README.md +++ b/README.md @@ -35,16 +35,18 @@ You can then add directives along these lines to your `BUILD.bazel` files: load("@bazel_pandoc//:pandoc.bzl", "pandoc") pandoc( - name = "foo", - src = "foo.md", - from_format = "markdown", - to_format = "latex", + name = "foo", # required + src = "foo.md", # required + from_format = "markdown", # optional, inferred from src extension by default + to_format = "latex", # optional, inferred from output extension by default + output = "awesome_doc.tex", # optional, derived from name and to_format by default ) ``` -In the example above, an output file called `foo.tex` will be created in -the `bazel-bin` directory. The `to_format` field is used to -automatically derive a file extension of the output file. +In the example above, an output file called `awesome_doc.tex` will be created +in the `bazel-bin` directory. + +At least one of the `to_format` or `output`attributes must be provided. # Platform support diff --git a/pandoc.bzl b/pandoc.bzl index d365128..cfaea14 100644 --- a/pandoc.bzl +++ b/pandoc.bzl @@ -85,7 +85,7 @@ _pandoc = rule( def _check_format(format, attr_name): if format not in PANDOC_EXTENSIONS: - fail("Unknown %{attr} format: %{format}".fmt(attr = attr_name, format = format)) + fail("Unknown `%{attr}` format: %{format}".fmt(attr = attr_name, format = format)) return format def _infer_output(name, to_format): @@ -99,9 +99,9 @@ def _infer_output(name, to_format): return name + "." + ext def pandoc(**kwargs): - if "from_format" in kwargs: - _check_format(kwargs["from_format"], "from_format") if "output" not in kwargs: + if "to_format" not in kwargs: + fail("One of `output` or `to_format` attributes must be provided") to_format = _check_format(kwargs["to_format"], "to_format") kwargs["output"] = _infer_output(kwargs["name"], to_format) _pandoc(**kwargs) diff --git a/sample/BUILD.bazel b/sample/BUILD.bazel index b4b1f68..14af1a8 100644 --- a/sample/BUILD.bazel +++ b/sample/BUILD.bazel @@ -1,19 +1,5 @@ load("//:pandoc.bzl", "PANDOC_EXTENSIONS", "pandoc") -# Simplest possible example, where the to_format is specified -pandoc( - name = "readme1", - src = "//:README.md", - to_format = "asciidoc", -) - -# Simplest possible example, where the output is specified -pandoc( - name = "readme2", - src = "//:README.md", - output = "readme2.html", -) - # Conversion of README to various formats for testing. [pandoc( name = "readme_" + fmt, @@ -21,3 +7,11 @@ pandoc( from_format = "markdown", to_format = fmt, ) for fmt in PANDOC_EXTENSIONS.keys()] + +# You can also specify the output, the format is then inferred from the extension, +# and the rule name is not used. +pandoc( + name = "gen_html_page", + src = "//:README.md", + output = "index.html", +) diff --git a/sample/README.md b/sample/README.md index 47c90f0..5eb669d 100644 --- a/sample/README.md +++ b/sample/README.md @@ -3,6 +3,9 @@ Once you have set up your workspace, you can generate the [README](../README.md) in a multitude of formats. + +## Target defined with `to_format` + For instance: ```sh @@ -11,7 +14,57 @@ bazel build @bazel_pandoc//sample:readme_html bazel build @bazel_pandoc//sample:readme_epub ``` -You can also produce the README in all formats know to the rule: +These targets are defined (actually with a _for loop_) with + +```python +pandoc( + name = "readme_plain", + src = "//:README.md", + from_format = "markdown", + to_format = "plain", +) +pandoc( + name = "readme_html", + src = "//:README.md", + from_format = "markdown", + to_format = "html", +) +pandoc( + name = "readme_epub", + src = "//:README.md", + from_format = "markdown", + to_format = "epub", +) +``` + +You notice that the output file is derived from the rule name: +- bazel-bin/sample/readme_plain.txt +- bazel-bin/sample/readme_html.html +- bazel-bin/sample/readme_epub.epub + +NB: `from_format` is optional and inferred from the file extension by default. + + +## Target defined with `output` + +It's also possible to specify the output + +```python +pandoc( + name = "gen_html_page", + src = "//:README.md", + output = "index.html", +) + +``` +As a result, +```sh +bazel build //sample:gen_html_page +``` +produces an HTML document in: +- bazel-bin/sample/index.html + +Finally can also produce the README in all formats know to the rule: ```sh bazel build @bazel_pandoc//sample/... From 0c23c7d26fcedf6a37cf9d2b2faa756bca447e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Mon, 2 Dec 2019 01:44:27 +0100 Subject: [PATCH 6/7] Make src single file and mandatory. --- pandoc.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandoc.bzl b/pandoc.bzl index cfaea14..0c4b297 100644 --- a/pandoc.bzl +++ b/pandoc.bzl @@ -75,7 +75,7 @@ _pandoc = rule( attrs = { "from_format": attr.string(), "options": attr.string_list(), - "src": attr.label(allow_files = True), + "src": attr.label(allow_single_file = True, mandatory = True), "to_format": attr.string(), "output": attr.output(mandatory = True), }, From c460f9c417c4c3c01fa43c5edf0fd8096d840ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Mon, 2 Dec 2019 01:50:48 +0100 Subject: [PATCH 7/7] self code review O:-) --- README.md | 2 +- pandoc.bzl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aadf97a..ab0aaba 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ pandoc( In the example above, an output file called `awesome_doc.tex` will be created in the `bazel-bin` directory. -At least one of the `to_format` or `output`attributes must be provided. +At least one of the `to_format` or `output` attributes must be provided. # Platform support diff --git a/pandoc.bzl b/pandoc.bzl index 0c4b297..d36a2a1 100644 --- a/pandoc.bzl +++ b/pandoc.bzl @@ -48,7 +48,6 @@ PANDOC_EXTENSIONS = { "textile": "textile", "zimwiki": "txt", } -PANDOC_FORMATS = PANDOC_EXTENSIONS.keys() def _pandoc_impl(ctx): toolchain = ctx.toolchains["@bazel_pandoc//:pandoc_toolchain_type"] @@ -59,7 +58,7 @@ def _pandoc_impl(ctx): if ctx.attr.to_format: cli_args.extend(["--to", ctx.attr.to_format]) cli_args.extend(["-o", ctx.outputs.output.path]) - cli_args.extend([ctx.files.src[0].path]) + cli_args.extend([ctx.file.src.path]) ctx.actions.run( mnemonic = "Pandoc", executable = toolchain.pandoc.files.to_list()[0].path,