summary refs log tree commit diff
diff options
context:
space:
mode:
authorfranck cuny <franck.cuny@gmail.com>2019-02-18 12:02:55 -0800
committerfranck cuny <franck.cuny@gmail.com>2019-02-18 12:02:55 -0800
commit22597fe6916200dada27f93f620a21f29cdb2e1c (patch)
tree5de5be9da2157628f27aa1abc2eae3970d364b7f
parentUpdate README (diff)
downloadpants.el-22597fe6916200dada27f93f620a21f29cdb2e1c.tar.gz
Cache list of targets.
Getting the list of targets can be extremely slow. Since the targets
don't change often, we can cache them. The first call will be slow,
however all further call will be extremely fast, since we read from a
file.

We rely on the modified time of the BUILD file to decide that our
cache is out of date.
-rw-r--r--pants.el51
1 files changed, 36 insertions, 15 deletions
diff --git a/pants.el b/pants.el
index 15d0789..5ab681c 100644
--- a/pants.el
+++ b/pants.el
@@ -184,30 +184,47 @@
         build-file
       (user-error "Could not find %s" pants-build-file))))
 
-(defun pants--get-targets ()
-  "Get the targets for the current file."
-  (let ((build-command (format "%s list %s:"
-                               (pants--build-command)
-                               (pants--get-build-file-for-current-buffer)))
-        (default-directory (pants--get-source-tree))
-        targets)
+(defun pants--read-targets-from-cache (cache-targets current-build-file)
+  "Returns a list of targets from the cache."
+  (let (targets)
     (with-temp-buffer
       (let (target)
-        (insert
-         (shell-command-to-string build-command))
+        (insert-file-contents-literally cache-targets)
         (goto-char (point-min))
         (while (re-search-forward "^\\(.+\\)$" nil t)
           (setq target (match-string 1))
           (push target targets))))
-    (push (format "%s::" (string-remove-prefix
-                          (pants--get-source-tree)
-                          (pants--get-build-file-for-current-buffer)))
+    (push (format "%s::"(string-remove-prefix (pants--get-source-tree) current-build-file))
           targets)
     targets))
 
-(define-compilation-mode pants-mode "pants"
-  (set (make-local-variable 'compilation-process-setup-function)
-       'pants--compilation-setup))
+(defun pants--populate-cache-targets (cache-targets current-build-file)
+  "Populates the cache with the targets."
+  (let ((output (get-buffer-create "*pants-list-targets*"))
+        (errors (format "%s%s/%s" (temporary-file-directory) "pants-targets" "errors"))
+        (default-directory (pants--get-source-tree))
+        (build-buffer (current-buffer)))
+    (make-directory (format "%s%s" (temporary-file-directory) "pants-targets") :parents)
+    (let ((status (call-process (format "%s%s" (pants--get-source-tree) pants-exec-name) nil `(,output ,errors) nil "list" current-build-file)))
+      (when (zerop status)
+          (with-current-buffer output
+            (write-file cache-targets)))
+      (switch-to-buffer build-buffer)
+      (when output (kill-buffer output))
+      (when errors (delete-file errors))
+      (pants--read-targets-from-cache cache-targets current-build-file))))
+
+(defun pants--get-path-cached-targets (current-build-file)
+  "Returns the path to the cached targets."
+  (format "%s%s/%s" (temporary-file-directory) "pants-targets" (secure-hash 'md5 current-build-file)))
+
+(defun pants--get-targets ()
+  "Returns the targets for the current file."
+  (let ((current-build-file (pants--get-build-file-for-current-buffer)))
+    (let ((cache-targets (pants--get-path-cached-targets current-build-file)))
+      (when (file-newer-than-file-p (format "%sBUILD" (pants--get-build-file-for-current-buffer)) cache-targets)
+        (pants--populate-cache-targets cache-targets current-build-file))
+      (read-targets-from-cache cache-targets))))
 
 (defun pants--replace-build-buffer (buffer new-content)
   (with-current-buffer buffer
@@ -216,6 +233,10 @@
       (insert-file-contents-literally new-content)
       (save-buffer))))
 
+(define-compilation-mode pants-mode "pants"
+  (set (make-local-variable 'compilation-process-setup-function)
+       'pants--compilation-setup))
+
 ;;;###autoload
 (defun pants-find-build-file ()
   "Finds the build file and if it exists, open it."