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)))