Lisp

This page documents rules for adding third-party Common and Emacs Lisp code to //piper/third_party.

IMPORTANT: Read go/thirdparty first.

General requirements

Third-party Common Lisp code goes in //piper/third_party/lisp.

Third-party Emacs Lisp code goes in //piper/third_party/elisp.

When creating a new directory, set ************************************* in the CL.

For Lisp-specific questions, email emailremoved@.

Each newly-created package should have an OWNERS file listing two people that can maintain the package, a LICENSE file containing the text of the code’s license agreement, a minimal BUILD file, a METADATA file, and a copy.bara.sky file to facilitate upgrading. Please CC emailremoved@ on your CL. They’ll make sure that everything is kosher style-wise. If you (or the reviewers) have any questions, don’t hesitate to add removed link to google group to the CL.

Common Lisp Requirements

Importing third_party code typically requires translating an ASDF .asd file into a BUILD file. There is no need to represent nested structure of the ASDF system definition; any linear order of source files suffices. To produce such an order, the following script may be followed as an example to help write a BUILD file, assuming use of SBCL and Quicklisp:

;; convert antik
(let (list)
  (sb-int:encapsulate
   'compile-file 'trace
   (lambda (realfun pathname &rest rest)
     (let ((sourceroot (namestring (truename "~/antik/"))))
       (when (eql (mismatch (namestring pathname) sourceroot)
                  (length sourceroot))
         (push (subseq (namestring pathname) (length sourceroot)) list))
       (apply realfun pathname rest))))
  (ql:quickload "antik")
  (sb-int:unencapsulate 'compile-file 'trace)
  (format t "srcs = [~%# serial~{~%~S,~}~%]~%" (reverse list))

Example output:

srcs = [
# serial
"init/package.lisp",
"init/utility.lisp",
# etc...
]

NOTE: Third-party Lisp code often elicits compiler warnings due to stylistic issues. You should not attempt to rectify those, but instead just add an option to ignore like nowarn = ['style-warning'] for each class of warning that is observed when using the Blaze lisp_library rule.

Emacs Lisp Specific Requirements

Third-party Emacs Lisp packages come from various sources and often distributed to Googlers’ workstations. You are responsible for ensuring the code is safe to use.

NOTE: The BUILD file targets and file names may not include hyphen characters, whereas this character is common in Emacs Lisp library names. The BUILD file should contain at least an elisp_library rule so that the library can be used in Blaze rules, and a test rule (e.g., elisp_test or build_test) so that Presubmit continuously byte-compiles the library and runs unit tests.

# Foo, a framework for frobbing Bars

load("//third_party/elisp/rules/elisp:defs.bzl", "elisp_library", "elisp_test")

package(default_visibility = ["//visibility:public"])

licenses(["restricted"])

exports_files(["LICENSE"])

elisp_library(
    name = "foo",
    srcs = ["foo.el"],
    load_path = ["."],
)

elisp_test(
    name = "foo_test",
    srcs = ["foo-test.el"],
    deps = [":foo"],
)

name is the name of the Blaze build target. After adding the elisp_library rule, you should try to build the package using blaze build :all. Note that warnings are treated like errors by default. To disable this behavior use the fatal_warnings = False attribute.

If the package’s unit tests don’t use ERT or require some special setup to run, you check in a Google-internal test driver file; see //piper/third_party/elisp/markdown_mode/google-test.el for an example. If the package doesn’t ship unit tests at all, use build_test instead of the elisp_test rule above so that Presubmit at least tries to byte-compile the package.

The directory //piper/third_party/elisp is for generic Emacs Lisp packages written by non-Googlers (either in pristine form or in a form that’s been improved for the Google environment). To add a subdirectory to the load-path you have to edit //piper/.../google.el; see go/emacs/debian#add for instructions.

Local changes make it hard to update to newer versions of third-party packages and should be avoided; prefer contributing patches upstream or, if that doesn’t work, use the advise functionality of Emacs Lisp.

To simplify updating to new versions, please add a go/copybara configuration. See //piper/third_party/elisp/kv/copy.bara.sky for an example.

If you want to use Bazel for Emacs Lisp packages outside of Google, feel free to use the rules_elisp rules.