diff options
| author | Yuan Fu | 2024-12-29 00:31:37 -0800 |
|---|---|---|
| committer | Yuan Fu | 2024-12-30 00:20:55 -0800 |
| commit | d9cfe1fe92ffda7e52dcb434e34bfdd1258f2688 (patch) | |
| tree | 3c147eaec2326177a851d5a1e305c4bfa28609eb | |
| parent | 5ec170985f4a9b2facc5ac883d0312f9cd270034 (diff) | |
| download | emacs-d9cfe1fe92ffda7e52dcb434e34bfdd1258f2688.tar.gz emacs-d9cfe1fe92ffda7e52dcb434e34bfdd1258f2688.zip | |
Add treesit-admin-generate-compatibility-report
This function can generate a HTML report on latest compatible
grammar versions for each major mode.
* admin/tree-sitter/compat-template.html: Update.
* admin/tree-sitter/treesit-admin.el:
(treesit-admin--validate-mode-lang): Change so that emacs 30 can
also run it.
(treesit-admin--find-latest-compatible-revision): Support
running checks with a different Emacs executable.
(treesit-admin--generate-compatibility-report): New function.
| -rw-r--r-- | admin/tree-sitter/compat-template.html | 29 | ||||
| -rw-r--r-- | admin/tree-sitter/treesit-admin.el | 71 |
2 files changed, 85 insertions, 15 deletions
diff --git a/admin/tree-sitter/compat-template.html b/admin/tree-sitter/compat-template.html index 487d4aacaef..f310d1b9ee5 100644 --- a/admin/tree-sitter/compat-template.html +++ b/admin/tree-sitter/compat-template.html | |||
| @@ -3,21 +3,42 @@ | |||
| 3 | <head> | 3 | <head> |
| 4 | <meta charset="utf-8"> | 4 | <meta charset="utf-8"> |
| 5 | <meta name="viewport" content="width=device-width, initial-scale=1"> | 5 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 6 | <title>Emacs tree-sitter language grammar version compatibility</title> | 6 | <title>Emacs tree-sitter grammar version compatibility report</title> |
| 7 | <style> | 7 | <style> |
| 8 | body { | 8 | body { |
| 9 | width: min(90vw, 40rem); | 9 | width: min(90vw, 40rem); |
| 10 | margin-left: auto; | 10 | margin: auto; |
| 11 | margin-top: 2rem; | ||
| 12 | font-family: ui-serif; | ||
| 13 | } | ||
| 14 | thead { | ||
| 15 | font-weight: bold; | ||
| 16 | } | ||
| 17 | table { | ||
| 18 | margin: auto; | ||
| 19 | } | ||
| 20 | table td { | ||
| 21 | padding: 0.5rem 1rem; | ||
| 22 | } | ||
| 23 | .head { | ||
| 24 | background: lightgreen; | ||
| 11 | } | 25 | } |
| 12 | </style> | 26 | </style> |
| 13 | </head> | 27 | </head> |
| 14 | <body> | 28 | <body> |
| 29 | <h1>Tree-sitter grammar compatibility for Emacs ___REPLACE_EMACS_VERSION___</h1> | ||
| 30 | <p>This is an auto-generated report of the latest compatible versions of tree-sitter grammars for each major mode. A <span class="head">green background</span> on the version indicates that the major mode is compatible with the latest commit in the upstream grammar repo.</p> | ||
| 31 | <p>This report is generated on ___REPLACE_TIME___.</p> | ||
| 15 | <table> | 32 | <table> |
| 16 | <thead> | 33 | <thead> |
| 17 | <tr><td>Language</td><td>Version</td></tr> | 34 | <tr> |
| 35 | <td>Major mode</td> | ||
| 36 | <td>Language</td> | ||
| 37 | <td>Latest compatible version</td> | ||
| 38 | </tr> | ||
| 18 | </thead> | 39 | </thead> |
| 19 | <tbody> | 40 | <tbody> |
| 20 | REPLACE | 41 | ___REPLACE_TABLE___ |
| 21 | </tbody> | 42 | </tbody> |
| 22 | </table> | 43 | </table> |
| 23 | </body> | 44 | </body> |
diff --git a/admin/tree-sitter/treesit-admin.el b/admin/tree-sitter/treesit-admin.el index 0787f6c9742..c2b95888652 100644 --- a/admin/tree-sitter/treesit-admin.el +++ b/admin/tree-sitter/treesit-admin.el | |||
| @@ -228,7 +228,8 @@ Return non-nil if all queries are valid, nil otherwise." | |||
| 228 | treesit-font-lock-settings))) | 228 | treesit-font-lock-settings))) |
| 229 | (all-queries-valid t)) | 229 | (all-queries-valid t)) |
| 230 | (dolist (setting settings) | 230 | (dolist (setting settings) |
| 231 | (let* ((query (treesit-font-lock-setting-query setting)) | 231 | ;; `treesit-font-lock-setting-query' isn't available in Emacs 30. |
| 232 | (let* ((query (car setting)) | ||
| 232 | (language (treesit-query-language query))) | 233 | (language (treesit-query-language query))) |
| 233 | ;; Validate query. | 234 | ;; Validate query. |
| 234 | (when (and (eq lang language) | 235 | (when (and (eq lang language) |
| @@ -253,13 +254,20 @@ Return non-nil if all queries are valid, nil otherwise." | |||
| 253 | settings))))) | 254 | settings))))) |
| 254 | 255 | ||
| 255 | (defun treesit-admin--find-latest-compatible-revision | 256 | (defun treesit-admin--find-latest-compatible-revision |
| 256 | (mode language source-alist grammar-dir) | 257 | (mode language source-alist grammar-dir &optional emacs-executable) |
| 257 | "Find the latest revision for LANGUAGE that's compatible with MODE. | 258 | "Find the latest revision for LANGUAGE that's compatible with MODE. |
| 258 | 259 | ||
| 259 | MODE, LANGUAGE, SOURCE-ALIST, GRAMMAR-DIR are the same as in | 260 | MODE, LANGUAGE, SOURCE-ALIST, GRAMMAR-DIR are the same as in |
| 260 | `treesit-admin--verify-major-mode-queries'. | 261 | `treesit-admin--verify-major-mode-queries'. |
| 261 | 262 | ||
| 262 | Return a plist (:version VERSION :head-version HEAD-VERSION). | 263 | By default, use the Emacs executable that spawned the current Emacs |
| 264 | session to validate grammars, but if EMACS-EXECUTABLE is non-nil, use it | ||
| 265 | instead. | ||
| 266 | |||
| 267 | Return a plist of the form | ||
| 268 | |||
| 269 | (:version VERSION :head-version HEAD-VERSION). | ||
| 270 | |||
| 263 | HEAD-VERSION is the version of the HEAD, VERSION is the latest | 271 | HEAD-VERSION is the version of the HEAD, VERSION is the latest |
| 264 | compatible version." | 272 | compatible version." |
| 265 | (let ((treesit-extra-load-path (list grammar-dir)) | 273 | (let ((treesit-extra-load-path (list grammar-dir)) |
| @@ -268,7 +276,8 @@ compatible version." | |||
| 268 | (recipe (alist-get language source-alist)) | 276 | (recipe (alist-get language source-alist)) |
| 269 | (workdir (make-temp-file "treesit-validate-workdir" t)) | 277 | (workdir (make-temp-file "treesit-validate-workdir" t)) |
| 270 | (emacs-executable | 278 | (emacs-executable |
| 271 | (expand-file-name invocation-name invocation-directory)) | 279 | (or emacs-executable |
| 280 | (expand-file-name invocation-name invocation-directory))) | ||
| 272 | head-version version exit-code) | 281 | head-version version exit-code) |
| 273 | (pcase-let ((`(,url ,revision ,source-dir ,cc ,c++ ,commit) | 282 | (pcase-let ((`(,url ,revision ,source-dir ,cc ,c++ ,commit) |
| 274 | recipe)) | 283 | recipe)) |
| @@ -301,11 +310,12 @@ compatible version." | |||
| 301 | (list :version version :head-version head-version))) | 310 | (list :version version :head-version head-version))) |
| 302 | 311 | ||
| 303 | (defun treesit-admin--last-compatible-grammar-for-modes | 312 | (defun treesit-admin--last-compatible-grammar-for-modes |
| 304 | (modes source-alist grammar-dir) | 313 | (modes source-alist grammar-dir &optional emacs-executable) |
| 305 | "Generate an HTML page listing latest compatible grammar versions. | 314 | "Generate an alist listing latest compatible grammar versions. |
| 306 | 315 | ||
| 307 | MODES, SOURCE-ALIST, GRAMMAR-DIR are the same as | 316 | MODES, SOURCE-ALIST, GRAMMAR-DIR are the same as |
| 308 | `treesit-admin--verify-major-mode-queries'. | 317 | `treesit-admin--verify-major-mode-queries'. If EMACS-EXECUTABLE is |
| 318 | non-nil, use it for validating queries. | ||
| 309 | 319 | ||
| 310 | Return an alist of an alist of a plist: | 320 | Return an alist of an alist of a plist: |
| 311 | 321 | ||
| @@ -320,14 +330,53 @@ VERSION and HEAD-VERSION in the plist are the same as in | |||
| 320 | (lambda (language) | 330 | (lambda (language) |
| 321 | (cons language | 331 | (cons language |
| 322 | (treesit-admin--find-latest-compatible-revision | 332 | (treesit-admin--find-latest-compatible-revision |
| 323 | mode language source-alist grammar-dir))) | 333 | mode language source-alist grammar-dir |
| 334 | emacs-executable))) | ||
| 324 | (treesit-admin--mode-languages mode)))) | 335 | (treesit-admin--mode-languages mode)))) |
| 325 | modes)) | 336 | modes)) |
| 326 | 337 | ||
| 327 | (defun treesit-admin-generate-compatibility-report () | 338 | (defun treesit-admin--generate-compatibility-report |
| 328 | "Generate a language compatibility report." | 339 | (modes out-file &optional emacs-executable) |
| 340 | "Generate a language compatibility report for MODES. | ||
| 341 | |||
| 342 | If EMACS-EXECUTABLE is non-nil, use it for validating queries. Write | ||
| 343 | the report to OUT-FILE." | ||
| 329 | (interactive) | 344 | (interactive) |
| 330 | ) | 345 | (with-temp-buffer |
| 346 | (let ((table (treesit-admin--last-compatible-grammar-for-modes | ||
| 347 | modes | ||
| 348 | treesit-admin--builtin-language-sources | ||
| 349 | "/tmp/treesit-grammar"))) | ||
| 350 | (dolist (entry table) | ||
| 351 | (let ((mode (car entry))) | ||
| 352 | (dolist (entry (cdr entry)) | ||
| 353 | (let* ((lang (car entry)) | ||
| 354 | (version (plist-get (cdr entry) :version)) | ||
| 355 | (head-version (plist-get (cdr entry) :head-version)) | ||
| 356 | (classname | ||
| 357 | (if (equal version head-version) "head" ""))) | ||
| 358 | (insert (format "<tr><td>%s</td><td>%s</td><td class=\"%s\">%s</td></tr>\n" | ||
| 359 | mode lang classname version))))))) | ||
| 360 | (let ((time (current-time-string nil t)) | ||
| 361 | (table-text (buffer-string)) | ||
| 362 | (emacs-version | ||
| 363 | (if emacs-executable | ||
| 364 | (with-temp-buffer | ||
| 365 | (call-process emacs-executable nil t nil | ||
| 366 | "-Q" "--batch" | ||
| 367 | "--eval" "(princ emacs-version)") | ||
| 368 | (buffer-string)) | ||
| 369 | emacs-version))) | ||
| 370 | (erase-buffer) | ||
| 371 | (insert-file-contents treesit-admin--compat-template-file-name) | ||
| 372 | (goto-char (point-min)) | ||
| 373 | (search-forward "___REPLACE_EMACS_VERSION___") | ||
| 374 | (replace-match emacs-version t) | ||
| 375 | (search-forward "___REPLACE_TIME___") | ||
| 376 | (replace-match (format "%s UTC" time) t) | ||
| 377 | (search-forward "___REPLACE_TABLE___") | ||
| 378 | (replace-match table-text t) | ||
| 379 | (write-region (point-min) (point-max) out-file)))) | ||
| 331 | 380 | ||
| 332 | (provide 'treesit-admin) | 381 | (provide 'treesit-admin) |
| 333 | 382 | ||