Function: bazel--fetch-central-registry

bazel--fetch-central-registry is a natively compiled function defined in bazel.el.

Signature

(bazel--fetch-central-registry)

Documentation

Download the Bazel Central Registry.

Return a hashtable mapping package names to their most recent versions.

Source Code

;; Defined in /nix/store/ws8pkszjvcad1rgzqw6wja7qxacylfhn-emacs-packages-deps/share/emacs/site-lisp/elpa/bazel-20261002.1510/bazel.el
(defun bazel--fetch-central-registry ()
  "Download the Bazel Central Registry.
Return a hashtable mapping package names to their most recent versions."
  (declare (ftype (function () hash-table)))
  ;; Cache the Git repository of the Bazel Central Registry locally.  We clone
  ;; into a new temporary directory each time.  Alternatively, we could keep a
  ;; single clone in a cache directory, but according to some benchmarks, that
  ;; would only be a bit faster (1.0 s vs. 1.3 s), and the added complexity
  ;; doesn’t seem worth it.  Be sure to bind ‘default-directory’ so that Git
  ;; runs on the correct host.
  (with-temp-buffer
    (let* ((git-dir
            (file-name-as-directory (make-temp-file "bcr-" :directory ".git")))
           (reporter
            (make-progress-reporter "Fetching Bazel Central Registry..." 0 4))
           (table (make-hash-table :test #'equal))
           (default-directory git-dir)
           (coding-system-for-read file-name-coding-system)
           (coding-system-for-write file-name-coding-system))
      ;; We only need the filenames in the registry, so we use a bare repisitory
      ;; and filter out blobs (--filter=blob:none).  We also don’t need history
      ;; (--depth=1) or tags (--no-tags).
      (vc-git-command nil 0 nil "clone" "--bare" "--single-branch"
                      "--filter=blob:none" "--depth=1" "--no-tags" "--"
                      bazel--central-registry-url ".")
      (progress-reporter-update reporter 1)
      ;; List the files in the modules directory.  The filenames are terminated
      ;; with NULL characters.  See
      ;; https://bazel.build/external/registry#index_registry for the directory
      ;; structure.  Instead of parsing the metadata.json files, we take the
      ;; module names and versions from the filenames.
      (vc-git-command t 0 nil "ls-tree" "-r" "-z" "--name-only" "--"
                      "HEAD" "modules")
      (progress-reporter-update reporter 2)
      (goto-char (point-min))
      ;; Look for source.json files and take module names and versions from
      ;; their filenames.
      (while (not (eobp))
        (let* ((begin (point))
               (end (+ begin (skip-chars-forward "^\0"))))
          (pcase (buffer-substring-no-properties begin end)
            ;; See https://bazel.build/rules/lib/globals/module#module and
            ;; https://bazel.build/external/module#version-format for allowed
            ;; module names and version strings.  We use somewhat relaxed
            ;; formats here.
            ((rx bos "modules/"
                 (let mod (any "a-z") (* (any "a-z" "0-9" ?. ?- ?_))) ?/
                 (let ver (+ (any "A-Z" "a-z" "0-9" ?. ?+ ?-)))
                 "/source.json" eos)
             ;; If the version is newer than the one in the hashtable, update
             ;; the hashtable accordingly.  Note that we ignore errors when
             ;; parsing versions; module versions can contain arbitrary strings
             ;; that ‘version-to-list’ can’t parse.  Ignoring errors is harmless
             ;; since users can’t rely on the returned version to be correct
             ;; anyway.  The logic below simply takes the last version found in
             ;; the buffer if version parsing fails.
             (let ((max (gethash mod table)))
               (unless (and max (ignore-errors (version<= ver max)))
                 (puthash mod ver table))))))
        ;; Skip over NULL character.
        (forward-char))
      (progress-reporter-update reporter 3)
      ;; We delete the temporary directory only on success, so that the user can
      ;; investigate if something goes wrong.
      (delete-directory git-dir :recursive)
      (progress-reporter-done reporter)
      table)))