diff --git a/.gitattributes b/.gitattributes index 1a3ff9d74..2fccf4006 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,4 @@ -# Copyright 2021 Google LLC +# Copyright 2021, 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,4 +20,4 @@ WORKSPACE text eol=lf # We enforce Unix-style line endings for the Stardoc files to address # https://github.com/bazelbuild/stardoc/issues/110. -/docs/*.md text eol=lf +/docs/*.org text eol=lf diff --git a/README.md b/README.md deleted file mode 120000 index e89233038..000000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -docs/index.md \ No newline at end of file diff --git a/README.org b/README.org new file mode 120000 index 000000000..252c8eb76 --- /dev/null +++ b/README.org @@ -0,0 +1 @@ +docs/index.org \ No newline at end of file diff --git a/build.py b/build.py index 1797ee74a..7e277d121 100755 --- a/build.py +++ b/build.py @@ -143,7 +143,7 @@ def docs(self) -> None: """Build the generated documentation files.""" output = self._run( [str(self._bazel_program), 'query', '--output=label', - r'filter("\.md\.generated$", kind("generated file", //...:*))'], + r'filter("\.org\.generated$", kind("generated file", //...:*))'], capture_stdout=True) targets = output.splitlines() bazel_bin = self._cwd / 'bazel-bin' diff --git a/docs/BUILD b/docs/BUILD index 6c53cda6f..95e49b10d 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -1,4 +1,4 @@ -# Copyright 2020, 2021 Google LLC +# Copyright 2020, 2021, 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,13 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@bazel_skylib//rules:copy_file.bzl", "copy_file") load("@bazel_skylib//rules:diff_test.bzl", "diff_test") load("@bazel_skylib//rules:run_binary.bzl", "run_binary") load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc") +load("@com_google_protobuf//:protobuf.bzl", "py_proto_library") stardoc( name = "elisp_doc", - out = "elisp_doc.md", + out = "elisp_doc.bin", + format = "proto", input = "//elisp:defs.bzl", deps = [ "//elisp:util_bzl", @@ -30,7 +33,8 @@ stardoc( stardoc( name = "emacs_doc", - out = "emacs_doc.md", + out = "emacs_doc.bin", + format = "proto", input = "//emacs:defs.bzl", deps = [ "//elisp:builtin_bzl", @@ -41,7 +45,8 @@ stardoc( stardoc( name = "repositories_doc", - out = "repositories_doc.md", + out = "repositories_doc.bin", + format = "proto", input = "//elisp:repositories.bzl", deps = ["//elisp:builtin_bzl"], ) @@ -53,20 +58,16 @@ DOCS = [ ] [ - # Bazel (including Stardoc) interprets all files as Latin-1, - # cf. https://docs.bazel.build/versions/4.1.0/build-ref.html#BUILD_files. - # However, our files all use UTF-8, leading to double encoding. Reverse - # that effect here. run_binary( - name = "reencode_" + doc, - srcs = [doc + "_doc.md"], - outs = [doc + ".md.generated"], + name = "gen_" + doc, + srcs = [doc + "_doc.bin"], + outs = [doc + ".org.generated"], args = [ "--", - "$(location :{}_doc.md)".format(doc), - "$(location :{}.md.generated)".format(doc), + "$(location :{}_doc.bin)".format(doc), + "$(location :{}.org.generated)".format(doc), ], - tool = ":reencode", + tool = ":org", ) for doc in DOCS ] @@ -75,15 +76,30 @@ DOCS = [ diff_test( name = doc + "_test", size = "small", - file1 = doc + ".md", - file2 = doc + ".md.generated", + file1 = doc + ".org", + file2 = doc + ".org.generated", ) for doc in DOCS ] py_binary( - name = "reencode", - srcs = ["reencode.py"], + name = "org", + srcs = ["org.py"], python_version = "PY3", srcs_version = "PY3", + tags = ["no-pytype"], # FIXME + deps = [":stardoc_output_py_proto"], +) + +py_proto_library( + name = "stardoc_output_py_proto", + srcs = [":stardoc_output.proto"], + srcs_version = "PY3", + tags = ["no-python-check"], +) + +copy_file( + name = "copy_stardoc_output_proto", + src = "@io_bazel_stardoc//stardoc/proto:stardoc_output.proto", + out = "stardoc_output.proto", ) diff --git a/docs/elisp.md b/docs/elisp.md deleted file mode 100644 index 769c7f790..000000000 --- a/docs/elisp.md +++ /dev/null @@ -1,224 +0,0 @@ - - -Defines rules to work with Emacs Lisp files in Bazel. - - - -## elisp_binary - -
-elisp_binary(name, data, deps, fatal_warnings, input_args, interactive, output_args, src)
-
- -Binary rule that loads a single Emacs Lisp file. -The source file is byte-compiled. At runtime, the compiled version is loaded -in batch mode unless `interactive` is `True`. - -**ATTRIBUTES** - - -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| data | List of files to be made available at runtime. | List of labels | optional | [] | -| deps | List of elisp_library dependencies. | List of labels | optional | [] | -| fatal_warnings | If True (the default), then byte compile warnings should be treated as errors. If False, they still show up in the output, but don’t cause the compilation to fail. Most targets should leave this attribute as True, because otherwise important issues might remain undetected. Set this attribute to False only for integrating third-party libraries that don’t compile cleanly and that you don’t control. | Boolean | optional | True | -| input_args | Indices of command-line arguments that represent input filenames. These number specify indices into the argv array. Negative indices are interpreted as counting from the end of the array. For example, the index 2 stands for argv[2], and the index -2 stands for argv[argc - 2]. When passing arguments to an emacs_binary program on the command line, the corresponding arguments are treated as filenames for input files and added to the inputFiles field of the manifest. This only has an effect for toolchains that specify wrap = True. | List of integers | optional | [] | -| interactive | Run Emacs in interactive instead of batch mode. | Boolean | optional | False | -| output_args | Indices of command-line arguments that represent output filenames. These number specify indices into the argv array. Negative indices are interpreted as counting from the end of the array. For example, the index 2 stands for argv[2], and the index -2 stands for argv[argc - 2]. When passing arguments to an emacs_binary program on the command line, the corresponding arguments are treated as filenames for output files and added to the outputFiles field of the manifest. This only has an effect for toolchains that specify wrap = True. | List of integers | optional | [] | -| src | Source file to load. | Label | required | | - - - - -## elisp_library - -
-elisp_library(name, data, deps, fatal_warnings, load_path, outs, srcs)
-
- -Byte-compiles Emacs Lisp source files and makes the compiled output -available to dependencies. All sources are byte-compiled. -`elisp_library`, `elisp_binary`, and `elisp_test` rules depending on this binary -can then use `load` or `require` to load them. - -By default, libraries need to be loaded using a filename relative to the -workspace root, i.e., package/file. If you want to add -further elements to the load path, use the `load_path` attribute. - -If there are multiple source files specified in `srcs`, these source files can -also load each other. However, it’s often preferable to only have one -`elisp_library` target per source file to make dependencies more obvious and -ensure that files get only loaded in their byte-compiled form. - -The source files in `srcs` can also list shared objects. The rule treats them -as Emacs modules and doesn’t try to byte-compile them. You can use -e.g. `cc_binary` with `linkshared = True` to create shared objects. - -**ATTRIBUTES** - - -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| data | List of files to be made available at runtime. | List of labels | optional | [] | -| deps | List of elisp_library dependencies. | List of labels | optional | [] | -| fatal_warnings | If True (the default), then byte compile warnings should be treated as errors. If False, they still show up in the output, but don’t cause the compilation to fail. Most targets should leave this attribute as True, because otherwise important issues might remain undetected. Set this attribute to False only for integrating third-party libraries that don’t compile cleanly and that you don’t control. | Boolean | optional | True | -| load_path | List of additional load path elements. The elements are directory names, which can be either relative or absolute. Relative names are relative to the current package. Absolute names are relative to the workspace root. To add a load path entry for the current package, specify . here. | List of strings | optional | [] | -| outs | List of byte-compiled Emacs Lisp files to be made available as targets. | List of labels | optional | | -| srcs | List of source files. These must either be Emacs Lisp files ending in .el, or module objects ending in .so, .dylib, or .dll. | List of labels | required | | - - - - -## elisp_manual - -
-elisp_manual(name, out, src)
-
- -Generates a [GNU_Texinfo](https://www.gnu.org/software/texinfo/) -manual from an [Org Mode file](https://orgmode.org/) using -[Org’s exporting functionality](https://orgmode.org/manual/Exporting.html). -You can then use -[`texi2any`](https://www.gnu.org/software/texinfo/manual/texinfo/html_node/Generic-Translator-texi2any.html) -to generate other document formats from the output file. - -**ATTRIBUTES** - - -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| out | Texinfo manual file to write; must end in .texi. | Label | required | | -| src | Org-mode file to use as manual source; must end in .org. | Label | required | | - - - - -## elisp_test - -
-elisp_test(name, data, deps, fatal_warnings, skip_tags, skip_tests, srcs)
-
- -Runs ERT tests that are defined in the source files. -The given source files should contain ERT tests defined with `ert-deftest`. -See the [ERT -manual](https://www.gnu.org/software/emacs/manual/html_node/ert/How-to-Write-Tests.html) -for details. The generated test binary loads all source files and executes all -tests like `ert-run-tests-batch-and-exit`. - -You can restrict the tests to be run using the `--test_filter` option. If set, -the value of `--test_filter` must be a Lisp expression usable as an [ERT test -selector](https://www.gnu.org/software/emacs/manual/html_node/ert/Test-Selectors.html). -You can also restrict the tests to be run using the `skip_tests` and -`skip_tags` rule attributes. These restrictions are additive, i.e., a test -only runs if it’s not suppressed by either facility. - -In coverage mode (i.e., when run under `bazel coverage`), all tests tagged with -the `:nocover` tag are also skipped. You can use this tag to skip tests that -normally pass, but don’t work under coverage for some reason. - -**ATTRIBUTES** - - -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| data | List of files to be made available at runtime. | List of labels | optional | [] | -| deps | List of elisp_library dependencies. | List of labels | optional | [] | -| fatal_warnings | If True (the default), then byte compile warnings should be treated as errors. If False, they still show up in the output, but don’t cause the compilation to fail. Most targets should leave this attribute as True, because otherwise important issues might remain undetected. Set this attribute to False only for integrating third-party libraries that don’t compile cleanly and that you don’t control. | Boolean | optional | True | -| skip_tags | List of test tags to skip. This attribute contains a list of tag names; if a test is tagged with one of the tags from this list, it is skipped. This can be useful to e.g. skip tests that are flaky or only work in interactive mode. Use the :tags keyword argument to ert-deftest to tag tests. | List of strings | optional | [] | -| skip_tests | List of tests to skip. This attribute contains a list of ERT test symbols; when running the test rule, these tests are skipped.

Most of the time, you should use [the skip-unless macro](https://www.gnu.org/software/emacs/manual/html_node/ert/Tests-and-Their-Environment.html) instead. The skip_tests attribute is mainly useful for third-party code that you don’t control. | List of strings | optional | [] | -| srcs | List of source files to load. | List of labels | required | | - - - - -## elisp_toolchain - -
-elisp_toolchain(name, emacs, execution_requirements, use_default_shell_env, wrap)
-
- -Toolchain rule for Emacs Lisp. -This toolchain configures how to run Emacs. -The executable passed to the `emacs` attribute must be a binary -that behaves like Emacs. -If `wrap` is `False`, Bazel calls it as is, passing arguments -that a normal Emacs binary would accept. -If `wrap` is `True`, Bazel calls the binary with a special `--manifest` option. -The value of the option is the filename of a JSON file containing a manifest. -The manifest specifies which files should be readable and/or writable by Emacs. -Toolchains can use this to sandbox Emacs, if desired. - -If `wrap` is `True`, the format of the command line is as follows: - -```bash -emacs --manifest=MANIFEST -- ARGS… -``` - -That is, the original arguments for Emacs are separated by a double hyphen -(`--`) so that argument parsers can distinguish between the `--manifest` option -and Emacs arguments. - -The manifest is a JSON object with the following keys: -- `root` can be either `EXECUTION_ROOT` or `RUNFILES_ROOT` and specifies - the root directory for relative file names. -- `loadPath` is a list of directory names making up the load path. -- `inputFiles` is a list of files that should be readable. -- `outputFiles` is a list of files that should be writable. -- `tags` is the list of tags for the current rule. - -When executing an action, file names are relative to the execution root. -Otherwise, file names are relative to the runfiles root. File names in -`inputFiles` or `outputFiles` can also be absolute; in this case they specify -temporary files that are deleted after the action completes, or files passed on -the command line interpreted according to the `input_args` and `output_args` -attributes of the `elisp_binary` rule. - -**ATTRIBUTES** - - -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| emacs | An executable file that behaves like the Emacs binary. Depending on whether wrap is True, Bazel invokes this executable with a command line like emacs --manifest=MANIFEST -- ARGS… or emacs ARGS…. The --manifest flag is only present if wrap is True. See the rule documentation for details. | Label | required | | -| execution_requirements | Execution requirements for compilation and test actions. | Dictionary: String -> String | optional | {} | -| use_default_shell_env | Whether actions should inherit the external shell environment. | Boolean | optional | False | -| wrap | Whether the binary given in the emacs attribute is a wrapper around Emacs proper. If True, Bazel passes a manifest file using the --manifest option. See the rule documentation for details. | Boolean | optional | False | - - - - -## EmacsLispInfo - -
-EmacsLispInfo(source_files, compiled_files, load_path, data_files, transitive_source_files,
-              transitive_compiled_files, transitive_load_path)
-
- -Provider for Emacs Lisp libraries. -The `elisp_library` rule produces this provider. - -Load path directory entries are structures with the following fields: -- `for_actions` is a string specifying the load directory to use for actions, - relative to the execution root. -- `for_runfiles` is a string specifying the load directory to use at runtime, - relative to the runfiles root. - -**FIELDS** - - -| Name | Description | -| :------------- | :------------- | -| source_files | A list of File objects containing the Emacs Lisp source files of this library. | -| compiled_files | A list of File objects containing the byte-compiled Emacs Lisp files and module objects of this library. | -| load_path | A list containing necessary load path additions for this library. The list elements are structures as described in the provider documentation. | -| data_files | A list of File objects that this library requires at runtime. | -| transitive_source_files | A depset of File objects containing the Emacs Lisp source files of this library and all its transitive dependencies. | -| transitive_compiled_files | A depset of File objects containing the byte-compiled Emacs Lisp files and module objects of this library and all its transitive dependencies. | -| transitive_load_path | A depset containing necessary load path additions for this library and all its transitive dependencies. The depset uses preorder traversal: entries for libraries closer to the root of the dependency graph come first. The depset elements are structures as described in the provider documentation. | - - diff --git a/docs/elisp.org b/docs/elisp.org new file mode 100644 index 000000000..a7829a0d6 --- /dev/null +++ b/docs/elisp.org @@ -0,0 +1,431 @@ +Defines rules to work with Emacs Lisp files in Bazel. + +* ~elisp_binary~ rule + +Binary rule that loads a single Emacs Lisp file. +The source file is byte-compiled. At runtime, the compiled version is loaded +in batch mode unless ~interactive~ is ~True~. + +** ~name~ attribute + +A unique name for this target. +Mandatory. + +- Type :: name + +** ~data~ attribute + +List of files to be made available at runtime. +Optional. + +- Type :: list of labels +- Default :: ~[]~ + +** ~deps~ attribute + +List of ~elisp_library~ dependencies. +Optional. + +- Type :: list of labels +- Default :: ~[]~ +- Required providers :: ~EmacsLispInfo~ + +** ~fatal_warnings~ attribute + +If ~True~ (the default), then byte compile warnings should be +treated as errors. If ~False~, they still show up in the output, but don’t +cause the compilation to fail. Most targets should leave this attribute as +~True~, because otherwise important issues might remain undetected. Set this +attribute to ~False~ only for integrating third-party libraries that don’t +compile cleanly and that you don’t control. +Optional. + +- Type :: Boolean +- Default :: ~True~ + +** ~input_args~ attribute + +Indices of command-line arguments that represent input +filenames. These number specify indices into the ~argv~ array. Negative +indices are interpreted as counting from the end of the array. For example, +the index ~2~ stands for ~argv[2]~, and the index ~-2~ stands for +~argv[argc - 2]~. When passing arguments to an ~emacs_binary~ program on the +command line, the corresponding arguments are treated as filenames for input +files and added to the ~inputFiles~ field of the manifest. This only has an +effect for toolchains that specify ~wrap = True~. +Optional. + +- Type :: list of integers +- Default :: ~[]~ + +** ~interactive~ attribute + +Run Emacs in interactive instead of batch mode. +Optional. + +- Type :: Boolean +- Default :: ~False~ + +** ~output_args~ attribute + +Indices of command-line arguments that represent output +filenames. These number specify indices into the ~argv~ array. Negative +indices are interpreted as counting from the end of the array. For example, +the index ~2~ stands for ~argv[2]~, and the index ~-2~ stands for +~argv[argc - 2]~. When passing arguments to an ~emacs_binary~ program on the +command line, the corresponding arguments are treated as filenames for output +files and added to the ~outputFiles~ field of the manifest. This only has an +effect for toolchains that specify ~wrap = True~. +Optional. + +- Type :: list of integers +- Default :: ~[]~ + +** ~src~ attribute + +Source file to load. +Mandatory. + +- Type :: label + +* ~elisp_library~ rule + +Byte-compiles Emacs Lisp source files and makes the compiled output +available to dependencies. All sources are byte-compiled. +~elisp_library~, ~elisp_binary~, and ~elisp_test~ rules depending on this binary +can then use ~load~ or ~require~ to load them. + +By default, libraries need to be loaded using a filename relative to the +workspace root, i.e., package/file. If you want to add +further elements to the load path, use the ~load_path~ attribute. + +If there are multiple source files specified in ~srcs~, these source files can +also load each other. However, it’s often preferable to only have one +~elisp_library~ target per source file to make dependencies more obvious and +ensure that files get only loaded in their byte-compiled form. + +The source files in ~srcs~ can also list shared objects. The rule treats them +as Emacs modules and doesn’t try to byte-compile them. You can use +e.g. ~cc_binary~ with ~linkshared = True~ to create shared objects. + +** ~name~ attribute + +A unique name for this target. +Mandatory. + +- Type :: name + +** ~data~ attribute + +List of files to be made available at runtime. +Optional. + +- Type :: list of labels +- Default :: ~[]~ + +** ~deps~ attribute + +List of ~elisp_library~ dependencies. +Optional. + +- Type :: list of labels +- Default :: ~[]~ +- Required providers :: ~EmacsLispInfo~ + +** ~fatal_warnings~ attribute + +If ~True~ (the default), then byte compile warnings should be +treated as errors. If ~False~, they still show up in the output, but don’t +cause the compilation to fail. Most targets should leave this attribute as +~True~, because otherwise important issues might remain undetected. Set this +attribute to ~False~ only for integrating third-party libraries that don’t +compile cleanly and that you don’t control. +Optional. + +- Type :: Boolean +- Default :: ~True~ + +** ~load_path~ attribute + +List of additional load path elements. +The elements are directory names, which can be either relative or absolute. +Relative names are relative to the current package. +Absolute names are relative to the workspace root. +To add a load path entry for the current package, specify ~.~ here. +Optional. + +- Type :: list of strings +- Default :: ~[]~ + +** ~outs~ attribute + +List of byte-compiled Emacs Lisp files to be made available +as targets. +Optional. + +- Type :: list of output files + +** ~srcs~ attribute + +List of source files. These must either be Emacs Lisp +files ending in ~.el~, or module objects ending in ~.so~, ~.dylib~, or +~.dll~. +Mandatory. + +- Type :: list of labels + +* ~elisp_manual~ rule + +Generates a [[https://www.gnu.org/software/texinfo/][GNU_Texinfo]] +manual from an [[https://orgmode.org/][Org Mode file]] using +[[https://orgmode.org/manual/Exporting.html][Org’s exporting functionality]]. +You can then use +[[https://www.gnu.org/software/texinfo/manual/texinfo/html_node/Generic-Translator-texi2any.html][~texi2any~]] +to generate other document formats from the output file. + +** ~name~ attribute + +A unique name for this target. +Mandatory. + +- Type :: name + +** ~out~ attribute + +Texinfo manual file to write; must end in ~.texi~. +Mandatory. + +- Type :: output file + +** ~src~ attribute + +Org-mode file to use as manual source; must end in ~.org~. +Mandatory. + +- Type :: label + +* ~elisp_test~ rule + +Runs ERT tests that are defined in the source files. +The given source files should contain ERT tests defined with ~ert-deftest~. +See the [[https://www.gnu.org/software/emacs/manual/html_node/ert/How-to-Write-Tests.html][ERT +manual]] +for details. The generated test binary loads all source files and executes all +tests like ~ert-run-tests-batch-and-exit~. + +You can restrict the tests to be run using the ~--test_filter~ option. If set, +the value of ~--test_filter~ must be a Lisp expression usable as an [[https://www.gnu.org/software/emacs/manual/html_node/ert/Test-Selectors.html][ERT test +selector]]. +You can also restrict the tests to be run using the ~skip_tests~ and +~skip_tags~ rule attributes. These restrictions are additive, i.e., a test +only runs if it’s not suppressed by either facility. + +In coverage mode (i.e., when run under ~bazel coverage~), all tests tagged with +the ~:nocover~ tag are also skipped. You can use this tag to skip tests that +normally pass, but don’t work under coverage for some reason. + +** ~name~ attribute + +A unique name for this target. +Mandatory. + +- Type :: name + +** ~data~ attribute + +List of files to be made available at runtime. +Optional. + +- Type :: list of labels +- Default :: ~[]~ + +** ~deps~ attribute + +List of ~elisp_library~ dependencies. +Optional. + +- Type :: list of labels +- Default :: ~[]~ +- Required providers :: ~EmacsLispInfo~ + +** ~fatal_warnings~ attribute + +If ~True~ (the default), then byte compile warnings should be +treated as errors. If ~False~, they still show up in the output, but don’t +cause the compilation to fail. Most targets should leave this attribute as +~True~, because otherwise important issues might remain undetected. Set this +attribute to ~False~ only for integrating third-party libraries that don’t +compile cleanly and that you don’t control. +Optional. + +- Type :: Boolean +- Default :: ~True~ + +** ~skip_tags~ attribute + +List of test tags to skip. This attribute contains a list +of tag names; if a test is tagged with one of the tags from this list, it is +skipped. This can be useful to e.g. skip tests that are flaky or only work in +interactive mode. Use the ~:tags~ keyword argument to ~ert-deftest~ to tag +tests. +Optional. + +- Type :: list of strings +- Default :: ~[]~ + +** ~skip_tests~ attribute + +List of tests to skip. This attribute contains a list of +ERT test symbols; when running the test rule, these tests are skipped. + +Most of the time, you should use [[https://www.gnu.org/software/emacs/manual/html_node/ert/Tests-and-Their-Environment.html][the ~skip-unless~ +macro]] +instead. The ~skip_tests~ attribute is mainly useful for third-party code that +you don’t control. +Optional. + +- Type :: list of strings +- Default :: ~[]~ + +** ~srcs~ attribute + +List of source files to load. +Mandatory. + +- Type :: list of labels + +* ~elisp_toolchain~ rule + +Toolchain rule for Emacs Lisp. +This toolchain configures how to run Emacs. +The executable passed to the ~emacs~ attribute must be a binary +that behaves like Emacs. +If ~wrap~ is ~False~, Bazel calls it as is, passing arguments +that a normal Emacs binary would accept. +If ~wrap~ is ~True~, Bazel calls the binary with a special ~--manifest~ option. +The value of the option is the filename of a JSON file containing a manifest. +The manifest specifies which files should be readable and/or writable by Emacs. +Toolchains can use this to sandbox Emacs, if desired. + +If ~wrap~ is ~True~, the format of the command line is as follows: + +#+BEGIN_SRC bash +emacs --manifest=MANIFEST -- ARGS… +#+END_SRC + +That is, the original arguments for Emacs are separated by a double hyphen +(~--~) so that argument parsers can distinguish between the ~--manifest~ option +and Emacs arguments. + +The manifest is a JSON object with the following keys: +- ~root~ can be either ~EXECUTION_ROOT~ or ~RUNFILES_ROOT~ and specifies + the root directory for relative file names. +- ~loadPath~ is a list of directory names making up the load path. +- ~inputFiles~ is a list of files that should be readable. +- ~outputFiles~ is a list of files that should be writable. +- ~tags~ is the list of tags for the current rule. + +When executing an action, file names are relative to the execution root. +Otherwise, file names are relative to the runfiles root. File names in +~inputFiles~ or ~outputFiles~ can also be absolute; in this case they specify +temporary files that are deleted after the action completes, or files passed on +the command line interpreted according to the ~input_args~ and ~output_args~ +attributes of the ~elisp_binary~ rule. + +** ~name~ attribute + +A unique name for this target. +Mandatory. + +- Type :: name + +** ~emacs~ attribute + +An executable file that behaves like the Emacs binary. +Depending on whether ~wrap~ is ~True~, Bazel invokes this executable +with a command line like ~emacs --manifest=MANIFEST -- ARGS…~ or ~emacs ARGS…~. +The ~--manifest~ flag is only present if ~wrap~ is ~True~. +See the rule documentation for details. +Mandatory. + +- Type :: label + +** ~execution_requirements~ attribute + +Execution requirements for compilation and test actions. +Optional. + +- Type :: dictionary string → string +- Default :: ~{}~ + +** ~use_default_shell_env~ attribute + +Whether actions should inherit the external shell environment. +Optional. + +- Type :: Boolean +- Default :: ~False~ + +** ~wrap~ attribute + +Whether the binary given in the ~emacs~ attribute is a +wrapper around Emacs proper. +If ~True~, Bazel passes a manifest file using the ~--manifest~ option. +See the rule documentation for details. +Optional. + +- Type :: Boolean +- Default :: ~False~ + +* ~EmacsLispInfo~ provider + +Provider for Emacs Lisp libraries. +The ~elisp_library~ rule produces this provider. + +Load path directory entries are structures with the following fields: +- ~for_actions~ is a string specifying the load directory to use for actions, + relative to the execution root. +- ~for_runfiles~ is a string specifying the load directory to use at runtime, + relative to the runfiles root. + +** ~source_files~ field + +A list of ~File~ objects containing +the Emacs Lisp source files of this library. + +** ~compiled_files~ field + +A list of ~File~ objects containing +the byte-compiled Emacs Lisp files and module objects of this library. + +** ~load_path~ field + +A list containing necessary load path +additions for this library. The list elements are structures as +described in the provider documentation. + +** ~data_files~ field + +A list of ~File~ objects that this library requires +at runtime. + +** ~transitive_source_files~ field + +A ~depset~ of ~File~ objects containing +the Emacs Lisp source files of this library +and all its transitive dependencies. + +** ~transitive_compiled_files~ field + +A ~depset~ of ~File~ objects containing +the byte-compiled Emacs Lisp files and module objects of this library +and all its transitive dependencies. + +** ~transitive_load_path~ field + +A ~depset~ containing necessary load path +additions for this library and all its transitive dependencies. +The ~depset~ uses preorder traversal: entries for libraries closer to the root +of the dependency graph come first. The ~depset~ elements are structures as +described in the provider documentation. + diff --git a/docs/emacs.md b/docs/emacs.md deleted file mode 100644 index 5c030a795..000000000 --- a/docs/emacs.md +++ /dev/null @@ -1,28 +0,0 @@ - - -Defines the rule `emacs_binary`, which compiles Emacs for use in Bazel. - - - -## emacs_binary - -
-emacs_binary(name, builtin_features, dump_mode, module_header, readme, srcs)
-
- -Builds Emacs from a source repository. -The resulting executable can be used to run the compiled Emacs. - -**ATTRIBUTES** - - -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| builtin_features | Label for a file into which to write the list of builtin features. If not provided, don’t write such a file. This is used by Gazelle. | Label | optional | | -| dump_mode | Dumping mode that Emacs will use. This can be either portable to use the portable dumper introduced in Emacs 27, or unexec to use the legacy “unexec” dumper. Starting with Emacs 27, portable is strongly recommended. | String | optional | "portable" | -| module_header | Label for a file target that will receive the emacs-module.h header. If not provided, don’t install the header. | Label | optional | | -| readme | The README file in the root of the Emacs repository. This is necessary to determine the source root directory. | Label | required | | -| srcs | All Emacs source files. | List of labels | required | | - - diff --git a/docs/emacs.org b/docs/emacs.org new file mode 100644 index 000000000..51f2c0b4b --- /dev/null +++ b/docs/emacs.org @@ -0,0 +1,57 @@ +Defines the rule ~emacs_binary~, which compiles Emacs for use in Bazel. + +* ~emacs_binary~ rule + +Builds Emacs from a source repository. +The resulting executable can be used to run the compiled Emacs. + +** ~name~ attribute + +A unique name for this target. +Mandatory. + +- Type :: name + +** ~builtin_features~ attribute + +Label for a file into which to write the list +of builtin features. If not provided, don’t write such a file. +This is used by Gazelle. +Optional. + +- Type :: output file + +** ~dump_mode~ attribute + +Dumping mode that Emacs will use. This can be either + ~portable~ to use the portable dumper introduced in Emacs 27, or ~unexec~ to +use the legacy “unexec” dumper. Starting with Emacs 27, ~portable~ is strongly +recommended. +Optional. + +- Type :: string +- Default :: ~"portable"~ + +** ~module_header~ attribute + +Label for a file target that will receive the +~emacs-module.h~ header. If not provided, don’t install the header. +Optional. + +- Type :: output file + +** ~readme~ attribute + +The README file in the root of the Emacs repository. +This is necessary to determine the source root directory. +Mandatory. + +- Type :: label + +** ~srcs~ attribute + +All Emacs source files. +Mandatory. + +- Type :: list of labels + diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index b1365acc9..000000000 --- a/docs/index.md +++ /dev/null @@ -1,83 +0,0 @@ -# Bazel rules for Emacs Lisp - -This repository provides a [Bazel][] integration for [Emacs Lisp][]. It is -modeled after the rules definitions for other languages, like the [C++ -rules][]. - -This is not an officially supported Google product. - -[Bazel]: https://bazel.build/ -[Emacs Lisp]: https://www.gnu.org/software/emacs/manual/html_node/elisp/ -[C++ rules]: https://docs.bazel.build/be/c-cpp.html - -## Usage - -Add a snippet like the following to your Bazel `WORKSPACE` file: - -```python -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "phst_rules_elisp", - sha256 = "b9fa0a049a915bf46063df8c80b2610518b686b5a78a0d93d75120f67902a76d", - strip_prefix = "rules_elisp-1dfe72da00da45427fa2e68485129b044a4a7621", - urls = [ - "https://github.com/phst/rules_elisp/archive/1dfe72da00da45427fa2e68485129b044a4a7621.zip", # 2022-02-16 - ], -) - -load( - "@phst_rules_elisp//elisp:repositories.bzl", - "rules_elisp_dependencies", - "rules_elisp_toolchains", -) - -rules_elisp_dependencies() - -rules_elisp_toolchains() -``` - -Then you can use the `elisp_library`, `elisp_binary`, and `elisp_test` rules. -See the [generated documentation][] and the examples in the `examples` -directory for details. - -[generated documentation]: elisp.md - -## Load path management - -The Emacs Lisp rules by default only add the workspace root directories to the -[load path][]. However, many Emacs Lisp libraries assume that their immediate -parent directory is present in the load path. To support such libraries, the -`elisp_library` rule supports an optional `load_path` attribute. You can -specify additional load path directories using this attribute. Relative -directories are relative to the Bazel package directory; absolute directories -are relative to the workspace root. A typical use case is to specify -`load_path = ["."]` to add the current package to the load path. - -[load path]: https://www.gnu.org/software/emacs/manual/html_node/elisp/Library-Search.html - -## Runfiles - -This repository also includes a library to access [runfiles][]. To use it, add -a build dependency on `@phst_rules_elisp//elisp/runfiles`. See the header -comments in `runfiles.el` for further usage hints. - -[runfiles]: https://docs.bazel.build/skylark/rules.html#runfiles - -* * * - -The following symbols are defined in `//elisp:defs.bzl`: - -{% include_relative elisp.md %} - -* * * - -The following symbols are defined in `//elisp:repositories.bzl`: - -{% include_relative repositories.md %} - -* * * - -The following symbols are defined in `//emacs:defs.bzl`: - -{% include_relative emacs.md %} diff --git a/docs/index.org b/docs/index.org new file mode 100644 index 000000000..da9e421b7 --- /dev/null +++ b/docs/index.org @@ -0,0 +1,70 @@ +* Bazel rules for Emacs Lisp + +This repository provides a [[https://bazel.build/][Bazel]] integration for +[[https://www.gnu.org/software/emacs/manual/html_node/elisp/][Emacs Lisp]]. It +is modeled after the rules definitions for other languages, like the +[[https://docs.bazel.build/be/c-cpp.html][C++ rules]]. + +This is not an officially supported Google product. + +** Usage + +Add a snippet like the following to your Bazel `WORKSPACE` file: + +#+BEGIN_SRC bazel-workspace +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "phst_rules_elisp", + sha256 = "b9fa0a049a915bf46063df8c80b2610518b686b5a78a0d93d75120f67902a76d", + strip_prefix = "rules_elisp-1dfe72da00da45427fa2e68485129b044a4a7621", + urls = [ + "https://github.com/phst/rules_elisp/archive/1dfe72da00da45427fa2e68485129b044a4a7621.zip", # 2022-02-16 + ], +) + +load( + "@phst_rules_elisp//elisp:repositories.bzl", + "rules_elisp_dependencies", + "rules_elisp_toolchains", +) + +rules_elisp_dependencies() + +rules_elisp_toolchains() +#+END_SRC + +Then you can use the ~elisp_library~, ~elisp_binary~, and ~elisp_test~ rules. +See the [[file:elisp.org][generated documentation]] and the examples in the +~examples~ directory for details. + +** Load path management + +The Emacs Lisp rules by default only add the workspace root directories to the +[[https://www.gnu.org/software/emacs/manual/html_node/elisp/Library-Search.html][load +path]]. However, many Emacs Lisp libraries assume that their immediate parent +directory is present in the load path. To support such libraries, the +~elisp_library~ rule supports an optional ~load_path~ attribute. You can +specify additional load path directories using this attribute. Relative +directories are relative to the Bazel package directory; absolute directories +are relative to the workspace root. A typical use case is to specify +~load_path = ["."]~ to add the current package to the load path. + +** Runfiles + +This repository also includes a library to access +[[https://docs.bazel.build/skylark/rules.html#runfiles][runfiles]]. To use it, +add a build dependency on ~@phst_rules_elisp//elisp/runfiles~. See the header +comments in ~runfiles.el~ for further usage hints. + +** Symbols defined in =//elisp:defs.bzl= + +#+INCLUDE: elisp.org + +** Symbols defined in =//elisp:repositories.bzl= + +#+INCLUDE: repositories.org + +** Symbols defined in =//emacs:defs.bzl= + +#+INCLUDE: emacs.org diff --git a/docs/org.py b/docs/org.py new file mode 100644 index 000000000..e9ed7ea69 --- /dev/null +++ b/docs/org.py @@ -0,0 +1,109 @@ +# Copyright 2021, 2022 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 +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Helper binary to convert Stardoc output into Org Mode format.""" + +import argparse +import pathlib +import re + +from phst_rules_elisp.docs import stardoc_output_pb2 + +def _main() -> None: + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument('input', type=pathlib.Path) + parser.add_argument('output', type=pathlib.Path) + opts = parser.parse_args() + module = stardoc_output_pb2.ModuleInfo.FromString(opts.input.read_bytes()) + # Force Unix-style line endings for consistent results. See + # https://github.com/bazelbuild/stardoc/issues/110. + with opts.output.open(mode='xt', encoding='utf-8', newline='\n') as file: + file.write(f'{_markdown(module.module_docstring)}\n\n') + for rule in module.rule_info: + file.write(f'* ~{rule.rule_name}~ rule\n\n') + file.write(f'{_markdown(rule.doc_string)}\n\n') + for attr in rule.attribute: + file.write(f'** ~{attr.name}~ attribute\n\n') + file.write(f'{_markdown(attr.doc_string)}\n') + file.write(f'{_MANDATORY[attr.mandatory]}.\n\n') + file.write(f'- Type :: {_ATTRIBUTE_TYPE[attr.type]}\n') + if attr.default_value: + file.write(f'- Default :: ~{attr.default_value}~\n') + if attr.provider_name_group: + group, = attr.provider_name_group + names = ', '.join( + f'~{name}~' for name in group.provider_name) + file.write(f'- Required providers :: {names}\n') + file.write('\n') + for provider in module.provider_info: + file.write(f'* ~{provider.provider_name}~ provider\n\n') + file.write(f'{_markdown(provider.doc_string)}\n\n') + for field in provider.field_info: + file.write(f'** ~{field.name}~ field\n\n') + file.write(f'{_markdown(field.doc_string)}\n\n') + for func in module.func_info: + file.write(f'* ~{func.function_name}~ function\n\n') + file.write(f'{_markdown(func.doc_string)}\n\n') + for param in func.parameter: + file.write(f'** ~{param.name}~ parameter\n\n') + file.write(f'{_markdown(func.doc_string)}\n') + file.write(f'{_MANDATORY[param.mandatory]}.\n\n') + if param.default_value: + file.write(f'- Default :: ~{param.default_value}~\n') + returns = getattr(func, 'return').doc_string + if returns: + file.write(f'- Returns :: {returns}\n\n') + if func.deprecated.doc_string: + raise ValueError( + f'unsupported deprecated function {func.function_name}') + if module.aspect_info: + raise ValueError('aspects are not yet supported') + +def _markdown(text: str) -> str: + """Convert a Markdown snippet to Org-mode.""" + # Bazel (including Stardoc) interprets all files as Latin-1, + # cf. https://docs.bazel.build/versions/4.1.0/build-ref.html#BUILD_files. + # However, our files all use UTF-8, leading to double encoding. Reverse + # that effect here. + text = text.strip().encode('latin-1').decode('utf-8') + # Use primitive text replacement, which should be good enough for the time + # being. + text = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'[[\2][\1]]', text) + text = re.sub(r'```(\w*\n[^`]+\n *)```', r'#+BEGIN_SRC \1#+END_SRC', text) + text = re.sub(r'`([^`]+)`', r'~\1~', text) + return text + +_ATTRIBUTE_TYPE = { + stardoc_output_pb2.NAME: 'name', + stardoc_output_pb2.INT: 'integer', + stardoc_output_pb2.LABEL: 'label', + stardoc_output_pb2.STRING: 'string', + stardoc_output_pb2.STRING_LIST: 'list of strings', + stardoc_output_pb2.INT_LIST: 'list of integers', + stardoc_output_pb2.LABEL_LIST: 'list of labels', + stardoc_output_pb2.BOOLEAN: 'Boolean', + stardoc_output_pb2.LABEL_STRING_DICT: 'dictionary string → label', + stardoc_output_pb2.STRING_DICT: 'dictionary string → string', + stardoc_output_pb2.STRING_LIST_DICT: 'dictionary string → list of strings', + stardoc_output_pb2.OUTPUT: 'output file', + stardoc_output_pb2.OUTPUT_LIST: 'list of output files', +} + +_MANDATORY = { + False: 'Optional', + True: 'Mandatory', +} + +if __name__ == '__main__': + _main() diff --git a/docs/reencode.py b/docs/reencode.py deleted file mode 100644 index 3ddc74254..000000000 --- a/docs/reencode.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2021 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 -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Helper binary to reencode a text file from UTF-8 to ISO-8859-1.""" - -import argparse -import pathlib - -def _main() -> None: - parser = argparse.ArgumentParser(allow_abbrev=False) - parser.add_argument('input', type=pathlib.Path) - parser.add_argument('output', type=pathlib.Path) - opts = parser.parse_args() - text = opts.input.read_text(encoding='utf-8') - # Force Unix-style line endings for consistent results. See - # https://github.com/bazelbuild/stardoc/issues/110. - with opts.output.open(mode='xt', encoding='latin-1', newline='\n') as file: - file.write(text) - -if __name__ == '__main__': - _main() diff --git a/docs/repositories.md b/docs/repositories.md deleted file mode 100644 index 8a51c881b..000000000 --- a/docs/repositories.md +++ /dev/null @@ -1,30 +0,0 @@ - - -Contains workspace functions to use Emacs Lisp rules. - - - -## rules_elisp_dependencies - -
-rules_elisp_dependencies()
-
- -Installs necessary dependencies for Emacs Lisp rules. - -Call this function in your `WORKSPACE` file. - - - - - -## rules_elisp_toolchains - -
-rules_elisp_toolchains()
-
- -Registers the default toolchains for Emacs Lisp. - - - diff --git a/docs/repositories.org b/docs/repositories.org new file mode 100644 index 000000000..e73c4971c --- /dev/null +++ b/docs/repositories.org @@ -0,0 +1,12 @@ +Contains workspace functions to use Emacs Lisp rules. + +* ~rules_elisp_dependencies~ function + +Installs necessary dependencies for Emacs Lisp rules. + +Call this function in your ~WORKSPACE~ file. + +* ~rules_elisp_toolchains~ function + +Registers the default toolchains for Emacs Lisp. + diff --git a/update_readme b/update_readme index 0b3cd8c45..9cf227332 100755 --- a/update_readme +++ b/update_readme @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2020, 2021 Google LLC +# Copyright 2020, 2021, 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -update-workspace-snippets docs/index.md examples/ext/WORKSPACE +update-workspace-snippets docs/index.org examples/ext/WORKSPACE