diff options
| author | Thanos Apollo <public@thanosapollo.org> | 2026-04-30 15:48:08 +0300 |
|---|---|---|
| committer | Thanos Apollo <public@thanosapollo.org> | 2026-04-30 15:52:18 +0300 |
| commit | ce74e1e3d72d3b734eb8cddfe32938499ef0ed98 (patch) | |
| tree | 37b75f995c42b2290cda188f5342d82a21fca7bf | |
| parent | 77c86b9f21b2d7ef3a3857695476f401408ee40c (diff) | |
repo,vc: cache metadata and gate popup by repo features
| -rw-r--r-- | lisp/forgejo-repo.el | 12 | ||||
| -rw-r--r-- | lisp/forgejo-vc.el | 93 |
2 files changed, 78 insertions, 27 deletions
diff --git a/lisp/forgejo-repo.el b/lisp/forgejo-repo.el index 5a3a944..8c234c1 100644 --- a/lisp/forgejo-repo.el +++ b/lisp/forgejo-repo.el @@ -107,6 +107,18 @@ When no buffer-local host is set, aggregates across all hosts." "SELECT DISTINCT owner, repo FROM issues WHERE host = ?" (list host)))))) +;;; Repo metadata sync + +(defun forgejo-repo-sync-metadata (host-url owner repo) + "Fetch and cache metadata for OWNER/REPO on HOST-URL. +Calls GET /repos/{owner}/{repo} and saves to the DB." + (forgejo-api-get + host-url (format "repos/%s/%s" owner repo) nil + (lambda (data _headers) + (when data + (forgejo-db-save-repo + (url-host (url-generic-parse-url host-url)) data))))) + ;;; Fetch user repos (defun forgejo-repo--fetch-user-repos () diff --git a/lisp/forgejo-vc.el b/lisp/forgejo-vc.el index 02c3f1d..cc0c805 100644 --- a/lisp/forgejo-vc.el +++ b/lisp/forgejo-vc.el @@ -39,6 +39,10 @@ (&optional owner repo)) (declare-function forgejo-api-post "forgejo-api.el" (host endpoint &optional params json-body callback)) +(declare-function forgejo-db-get-repo "forgejo-db.el" + (host owner name)) +(declare-function forgejo-repo-sync-metadata "forgejo-repo.el" + (host-url owner repo)) ;;; Repo counts (async, cached per-directory) @@ -63,29 +67,56 @@ "Return cached open PR count for the current repo, or nil." (cdr (gethash (forgejo-vc--ensure-repo-key) forgejo-vc--counts))) +(defun forgejo-vc--repo-metadata () + "Return cached repo metadata alist for the current repo, or nil." + (when-let* ((context (forgejo-vc--repo-from-remote)) + (host-url (nth 0 context)) + (host (url-host (url-generic-parse-url host-url))) + (owner (nth 1 context)) + (repo (nth 2 context))) + (forgejo-db-get-repo host owner repo))) + +(defun forgejo-vc--no-issues-p () + "Return non-nil when the current repo has issues disabled." + (when-let* ((meta (forgejo-vc--repo-metadata))) + (not (alist-get 'has_issues meta)))) + +(defun forgejo-vc--no-pulls-p () + "Return non-nil when the current repo has pull requests disabled." + (when-let* ((meta (forgejo-vc--repo-metadata))) + (not (alist-get 'has_pull_requests meta)))) + (defun forgejo-vc--fetch-counts () - "Fetch open issue/PR counts for the current repo asynchronously." + "Fetch open issue/PR counts for the current repo asynchronously. +Also syncs repo metadata if not yet cached." (when-let* ((context (forgejo-vc--repo-from-remote)) (host (nth 0 context)) (owner (nth 1 context)) (repo (nth 2 context)) (key (format "%s/%s" owner repo))) - (forgejo-api-get - host (format "repos/%s/%s/issues" owner repo) - '(("state" . "open") ("type" . "issues") ("limit" . "1")) - (lambda (_data headers) - (let ((existing (gethash key forgejo-vc--counts))) - (puthash key - (cons (plist-get headers :total-count) (cdr existing)) - forgejo-vc--counts)))) - (forgejo-api-get - host (format "repos/%s/%s/issues" owner repo) - '(("state" . "open") ("type" . "pulls") ("limit" . "1")) - (lambda (_data headers) - (let ((existing (gethash key forgejo-vc--counts))) - (puthash key - (cons (car existing) (plist-get headers :total-count)) - forgejo-vc--counts)))))) + (let ((hostname (url-host (url-generic-parse-url host)))) + (unless (forgejo-db-get-repo hostname owner repo) + (forgejo-repo-sync-metadata host owner repo)) + (when-let* ((meta (forgejo-db-get-repo hostname owner repo)) + ((alist-get 'has_issues meta))) + (forgejo-api-get + host (format "repos/%s/%s/issues" owner repo) + '(("state" . "open") ("type" . "issues") ("limit" . "1")) + (lambda (_data headers) + (let ((existing (gethash key forgejo-vc--counts))) + (puthash key + (cons (plist-get headers :total-count) (cdr existing)) + forgejo-vc--counts))))) + (when-let* ((meta (forgejo-db-get-repo hostname owner repo)) + ((alist-get 'has_pull_requests meta))) + (forgejo-api-get + host (format "repos/%s/%s/issues" owner repo) + '(("state" . "open") ("type" . "pulls") ("limit" . "1")) + (lambda (_data headers) + (let ((existing (gethash key forgejo-vc--counts))) + (puthash key + (cons (car existing) (plist-get headers :total-count)) + forgejo-vc--counts)))))))) ;;; Git detection (pure: git command -> data) @@ -531,17 +562,25 @@ and mark it as manually merged after a successful push." "Forgejo operations for the current repository." :group "View" "i" ((lambda () - (if-let* ((n (forgejo-vc--issue-count))) - (format "Issues (%s)" (propertize (number-to-string n) - 'face 'warning)) - "Issues")) - forgejo-vc-issues) + (cond + ((forgejo-vc--no-issues-p) "Issues (disabled)") + ((forgejo-vc--issue-count) + (format "Issues (%s)" (propertize + (number-to-string (forgejo-vc--issue-count)) + 'face 'warning))) + (t "Issues"))) + forgejo-vc-issues + :inapt-if (lambda () (forgejo-vc--no-issues-p))) "p" ((lambda () - (if-let* ((n (forgejo-vc--pr-count))) - (format "Pull requests (%s)" (propertize (number-to-string n) - 'face 'forgejo-open-face)) - "Pull requests")) - forgejo-vc-pulls) + (cond + ((forgejo-vc--no-pulls-p) "Pull requests (disabled)") + ((forgejo-vc--pr-count) + (format "Pull requests (%s)" (propertize + (number-to-string (forgejo-vc--pr-count)) + 'face 'forgejo-open-face))) + (t "Pull requests"))) + forgejo-vc-pulls + :inapt-if (lambda () (forgejo-vc--no-pulls-p))) :group "PR" "s" ("Submit PR" forgejo-vc-submit :c-u "force push" :inapt-if (lambda () (forgejo-vc--no-remote-p))) |
