Function: bazel-finish-compilation

bazel-finish-compilation is a natively compiled function defined in bazel.el.

Signature

(bazel-finish-compilation BUFFER MESSAGE)

Documentation

Parse Bazel build output in BUFFER.

If the option ‘bazel-display-coverage’ is non-nil and there are references to coverage results in BUFFER, attempt to display the line coverage status in buffers that are visiting files with coverage information. If the option ‘bazel-fix-visibility’ is non-nil, attempt to add missing target visibility attributes using Buildozer. MESSAGE is the status message for the Bazel process exit; "finished\\n" if Bazel completed successfully. This function is suitable for ‘compilation-finish-functions’.

Source Code

;; Defined in /nix/store/ws8pkszjvcad1rgzqw6wja7qxacylfhn-emacs-packages-deps/share/emacs/site-lisp/elpa/bazel-20261002.1510/bazel.el
(defun bazel-finish-compilation (buffer message)
  "Parse Bazel build output in BUFFER.
If the option ‘bazel-display-coverage’ is non-nil and there are
references to coverage results in BUFFER, attempt to display the
line coverage status in buffers that are visiting files with
coverage information.  If the option ‘bazel-fix-visibility’ is
non-nil, attempt to add missing target visibility attributes
using Buildozer.  MESSAGE is the status message for the Bazel
process exit; \"finished\\n\" if Bazel completed successfully.
This function is suitable for ‘compilation-finish-functions’."
  (declare (ftype (function (buffer string) null)))
  (cl-check-type buffer buffer)
  (cl-check-type message string)
  (when (and bazel-display-coverage (buffer-live-p buffer)
             (string-equal message "finished\n"))
    (with-current-buffer buffer
      (let ((case-fold-search (file-name-case-insensitive-p default-directory))
            (search-spaces-regexp nil)
            (remote (file-remote-p default-directory))
            (files ()))
        (when (or (not remote) (eq bazel-display-coverage t))
          ;; First collect potential coverage files.  If there are none (typical
          ;; case), we don’t have to hit the filesystem.
          (save-excursion
            (goto-char (point-min))
            ;; Parse Bazel output.  It’s supposed to be stable and easy to
            ;; parse, cf. https://bazel.build/run/scripts#parsing-output.  We
            ;; assume that coverage instrumentation files are always called
            ;; “coverage.dat”.
            (while (re-search-forward
                    (rx bol "  " (group ?/ (+ nonl) "/coverage.dat") eol)
                    nil t)
              (let ((file (match-string-no-properties 1)))
                ;; The coverage files are external filenames, so quote them (to
                ;; avoid clashes with filename handlers) and make them remote if
                ;; necessary.
                (push (concat remote (file-name-quote file)) files)))))
        (when files
          ;; Only continue if we’re in a Bazel repository.
          (when-let* ((root (bazel--repository-root default-directory)))
            ;; COVERAGE maps buffers to hashtables that in turn map line numbers
            ;; to ‘bazel--coverage’ structures.  We first collect coverage
            ;; information into this hashtable to correctly deal with duplicate
            ;; file sections.
            (let ((coverage (make-hash-table :test #'eq)))
              (dolist (file files)
                (with-temp-buffer
                  ;; Don’t bail out if the coverage file can’t be read.  Maybe
                  ;; it has already been garbage-collected.
                  (when (ignore-error file-missing (insert-file-contents file))
                    (bazel--parse-coverage root coverage))))
              (maphash #'bazel--display-coverage coverage)))))))
  (when (and bazel-fix-visibility (string-prefix-p "exited abnormally" message))
    (with-current-buffer buffer
      (let ((case-fold-search nil)
            (search-spaces-regexp nil)
            (infos ())
            (ask (eq bazel-fix-visibility 'ask)))
        (save-excursion
          ;; First search for error messages concerning visibility.  If there
          ;; are none (typical case), we don’t have to hit the filesystem.
          (goto-char (point-min))
          (while (re-search-forward
                  (rx bol "ERROR: " (+ (any alnum ?/ ?- ?. ?_)) ?:
                      (+ digit) ?: (+ digit) ": "
                      (group
                       (+ nonl) "Visibility error:\n"
                       "target '"
                       (group (+ (any "a-z" "A-Z" "0-9"
                                      ?- "!%@^_` #$&()*+,;<=>?[]{|}~/.:")))
                       "' is not visible from\n"
                       "target '"
                       (group (+ (any "a-z" "A-Z" "0-9"
                                      ?- "!%@^_` #$&()*+,;<=>?[]{|}~/.:")))
                       "'" eol))
                  nil t)
            (push (list (match-string-no-properties 3)
                        (match-string-no-properties 2)
                        (match-beginning 1)
                        (match-end 1))
                  infos)))
        (when infos
          ;; Only continue if we’re in a Bazel repository.
          (when-let* ((root (bazel--repository-root default-directory)))
            (pcase-dolist (`(,source ,dest ,begin ,end) (nreverse infos))
              (bazel--add-visibility root source dest begin end ask)))))))
  nil)