From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Konstantin Kharlamov Newsgroups: gmane.emacs.bugs Subject: bug#68579: [PATCH v2] Support a local repo as URL in treesit-language-source-alist Date: Sat, 20 Jan 2024 14:56:29 +0300 Message-ID: <20240120115637.25253-1-Hi-Angel@yandex.ru> References: <0ffc2f474cf84ed3c63aa82091c967807e5ca0e6.camel@yandex.ru> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="10116"; mail-complaints-to="usenet@ciao.gmane.io" To: 68579@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Jan 20 12:57:12 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rR9yJ-0002VI-7E for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 20 Jan 2024 12:57:11 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rR9y9-00044t-E7; Sat, 20 Jan 2024 06:57:01 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rR9y7-00044H-TP for bug-gnu-emacs@gnu.org; Sat, 20 Jan 2024 06:56:59 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rR9y7-0001tk-Ls for bug-gnu-emacs@gnu.org; Sat, 20 Jan 2024 06:56:59 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1rR9yA-00058x-4e for bug-gnu-emacs@gnu.org; Sat, 20 Jan 2024 06:57:02 -0500 X-Loop: help-debbugs@gnu.org In-Reply-To: <0ffc2f474cf84ed3c63aa82091c967807e5ca0e6.camel@yandex.ru> Resent-From: Konstantin Kharlamov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Jan 2024 11:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 68579 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 68579-submit@debbugs.gnu.org id=B68579.170575181819745 (code B ref 68579); Sat, 20 Jan 2024 11:57:02 +0000 Original-Received: (at 68579) by debbugs.gnu.org; 20 Jan 2024 11:56:58 +0000 Original-Received: from localhost ([127.0.0.1]:33060 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rR9y5-00058N-M4 for submit@debbugs.gnu.org; Sat, 20 Jan 2024 06:56:58 -0500 Original-Received: from forward101a.mail.yandex.net ([178.154.239.84]:39250) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rR9y1-000587-Da for 68579@debbugs.gnu.org; Sat, 20 Jan 2024 06:56:55 -0500 Original-Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:2912:0:640:56:0]) by forward101a.mail.yandex.net (Yandex) with ESMTP id 8F46A608CD for <68579@debbugs.gnu.org>; Sat, 20 Jan 2024 14:56:47 +0300 (MSK) Original-Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id juN1JVCj4Gk0-WlnnHMLF; Sat, 20 Jan 2024 14:56:47 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1705751807; bh=Vy+IMGAkPPBOKivI9o92V6NSLv+torWcFujN0TE5p5c=; h=To:Message-ID:Date:Subject:From; b=j/66wC5CD9uOoILEY3Ah2YJCs019N9fVBaLMcsgjFmaaMnmFijynUED2OYB8iXgGK 268vLyydJwYUeLKIxK3aI+irKp1QlB3/Vu5rOrkUk5Ax+FPMZI7zri+9PABBcBLmO8 PN0jz42rNAth8plb+RCKbzQ1jAcg0tEOAzrtQCww= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru X-Mailer: git-send-email 2.43.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:278599 Archived-At: Sometimes people may need to bisect to find specific revision in a grammar repo. In this case they'd want to point the URL to the local repo to avoid cloning it on every rebuild. So add support for full path in treesit-language-source-alist. * lisp/treesit.el (treesit--install-language-grammar-1): Test if URL starts with / meaning that the URL is a local path. Then if it is, avoid cloning the repo and removing the path on success. (treesit--git-clone-repo): Factor out the code for cloning to a separate function. (treesit--git-checkout-branch): A helper to checkout the revision for cases where we didn't clone the repo but want it to point the revision. --- v2: 1. Regarding discussion about (file-name-absolute-p) and (file-accessible-directory-p), I figured that if we only test whether the file is accessible, we can lift the restriction of it being an absolute directory. So now I test for accessibility. 2. I also removed my comment in variable initialization because it's obsolete and no longer useful. 3. I also couldn't squash the (if url-is-path (when revision (treesit--git-checkout-branch url revision)) to (and url-is-path revision (treesit--git-checkout-branch url revision)) because that would change the semantics: note that there's an `(if` which checks whether we're dealing with a local path, and then in "else" branch (which is not in the snippet) we clone the repo. Changing the code as requested would result in the code cloning the repo when it's a local path but the revision wasn't set. 4. I hope it's not a problem: I made use of the word `path` inside documentation for `treesit-language-source-alist`. It just seems to sound awkward repeating the word "directory" twice, and I think it's clear from the context that these are synonyms. Hopefully I didn't miss anything 😅 (Eli Zaretskii): * start sentences with capital letter and put 2 spaces after the dot * replace "path" with "dir" and "directory" in code and docs * capitalize and unquote arg names in the docs * (treesit--git-clone-repo): document REVISION being nil * call (expand-file-name) on the URL * added a NEWS entry * changed (treesit-language-source-alist) docs to shortly mention the workflow of building the grammar from a local path etc/NEWS | 8 ++++++++ lisp/treesit.el | 49 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 735a05f6579..19b06ea4c66 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1832,6 +1832,14 @@ The 'test' parameter is omitted if it is 'eql' (the default), as is 'data' if empty. 'rehash-size', 'rehash-threshold' and 'size' are always omitted, and ignored if present when the object is read back in. ++++ +** 'treesit-install-language-grammar' can handle local directory as URL. +It is now possible to pass a directory of a local repository as URL +inside 'treesit-language-source-alist', so that calling +'treesit-install-language-grammar' would avoid cloning the repository. +It may be useful for example for the purposes of bisecting a +treesitter grammar. + * Changes in Emacs 30.1 on Non-Free Operating Systems diff --git a/lisp/treesit.el b/lisp/treesit.el index c8b473c7bb8..19dcbe324aa 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -3410,14 +3410,16 @@ treesit-explore-mode ;;; Install & build language grammar (defvar treesit-language-source-alist nil - "Configuration for downloading and installing tree-sitter language grammars. + "Configuration for downloading and installing tree-sitter language +grammars. The grammar can also be built from a local directory if +URL is an existing local path to the repo. The value should be an alist where each element has the form (LANG . (URL REVISION SOURCE-DIR CC C++)) Only LANG and URL are mandatory. LANG is the language symbol. -URL is the Git repository URL for the grammar. +URL is the Git repository URL or directory name for the grammar. REVISION is the Git tag or branch of the desired version, defaulting to the latest default branch. @@ -3551,6 +3553,26 @@ treesit--call-process-signal (buffer-string))) (erase-buffer))) +(defun treesit--git-checkout-branch (repo-dir revision) + "Checkout REVISION in a repo located in REPO-DIR." + (treesit--call-process-signal + "git" nil t nil "-C" repo-dir "checkout" revision)) + +(defun treesit--git-clone-repo (url revision workdir) + "Clone repo pointed by URL at commit REVISION to WORKDIR. + +REVISION may be nil, in which case the cloned repo will be at its +default branch." + (message "Cloning repository") + ;; git clone xxx --depth 1 --quiet [-b yyy] workdir + (if revision + (treesit--call-process-signal + "git" nil t nil "clone" url "--depth" "1" "--quiet" + "-b" revision workdir) + (treesit--call-process-signal + "git" nil t nil "clone" url "--depth" "1" "--quiet" + workdir))) + (defun treesit--install-language-grammar-1 (out-dir lang url &optional revision source-dir cc c++) "Install and compile a tree-sitter language grammar library. @@ -3564,8 +3586,12 @@ treesit--install-language-grammar-1 `treesit-language-source-alist'. If anything goes wrong, this function signals an error." (let* ((lang (symbol-name lang)) + (maybe-repo-dir (expand-file-name url)) + (url-is-dir (file-accessible-directory-p maybe-repo-dir)) (default-directory (make-temp-file "treesit-workdir" t)) - (workdir (expand-file-name "repo")) + (workdir (if url-is-dir + maybe-repo-dir + (expand-file-name "repo"))) (source-dir (expand-file-name (or source-dir "src") workdir)) (cc (or cc (seq-find #'executable-find '("cc" "gcc" "c99")) ;; If no C compiler found, just use cc and let @@ -3580,15 +3606,10 @@ treesit--install-language-grammar-1 (lib-name (concat "libtree-sitter-" lang soext))) (unwind-protect (with-temp-buffer - (message "Cloning repository") - ;; git clone xxx --depth 1 --quiet [-b yyy] workdir - (if revision - (treesit--call-process-signal - "git" nil t nil "clone" url "--depth" "1" "--quiet" - "-b" revision workdir) - (treesit--call-process-signal - "git" nil t nil "clone" url "--depth" "1" "--quiet" - workdir)) + (if url-is-dir + (when revision + (treesit--git-checkout-branch workdir revision)) + (treesit--git-clone-repo url revision workdir)) ;; We need to go into the source directory because some ;; header files use relative path (#include "../xxx"). ;; cd "${sourcedir}" @@ -3635,7 +3656,9 @@ treesit--install-language-grammar-1 ;; Ignore errors, in case the old version is still used. (ignore-errors (delete-file old-fname))) (message "Library installed to %s/%s" out-dir lib-name)) - (when (file-exists-p workdir) + ;; Remove workdir if it's not a repo owned by user and we + ;; managed to create it in the first place. + (when (and (not url-is-dir) (file-exists-p workdir)) (delete-directory workdir t))))) ;;; Etc -- 2.43.0