forked from emacs-taskrunner/emacs-taskrunner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtaskrunner-java.el
159 lines (146 loc) · 5.89 KB
/
taskrunner-java.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
;;; taskrunner-java.el --- Provide functions to retrieve java build system targets -*- lexical-binding: t; -*-
;; Copyright (C) 2019 Yavor Konstantinov
;;;; Commentary:
;; Provide function for extracting java build system targets.
;; Support included for:
;; - Ant
;; - Gradle
;;;; Code:
(require 'cl-lib)
(require 'subr-x)
;;;; Variables
(defcustom taskrunner-gradle-heading-regexps
'("Build tasks\n-+\n"
"Help tasks\n-+\n"
"Verification tasks\n-+\n"
"Documentation tasks\n-+\n"
"Distribution tasks\n-+\n"
"Other tasks\n-+\n"
"Build Setup tasks\n-+\n"
"IDE tasks tasks\n-+\n"
)
"Regular expressions used to locate task section headings from gradle output."
:type 'list
:group 'taskrunner)
;;;; Functions
;; These are here just to silence the bytecompiler. They are defined in
;; `taskrunner.el' and will be loaded later on but due to these files being
;; required before the function being loaded, a warning is emitted.
(declare-function taskrunner--narrow-to-line "ext:taskrunner")
(declare-function taskrunner--make-task-buff-name "ext:taskrunner")
;; Each block contains several tasks which can be executed.
;; The block has the following form:
;; TASK-HEADING
;; ------------ (underline for the heading)
;; task 1
;; task 2
;; ...
;; task n-1
;; task n
;; BLANK-LINE
;; This function narrows to the region which starts directly after the underline
;; for the heading and ends at the blank line separating each block.
(defun taskrunner--retrieve-gradle-heading-tasks (heading)
"Retrieve the gradle tasks below the heading HEADING and return as list."
(widen)
(goto-char (point-min))
(let ((beg (re-search-forward heading nil t)))
(when beg
(narrow-to-region beg
(progn
(re-search-forward "^$" nil t)
;; Go up a line so the empty line at the end of the block
;; is not included in the output
(forward-line -1)
(line-end-position)))
(cl-map 'list (lambda (elem)
(concat "GRADLE" " " (car (split-string elem " "))))
(split-string (buffer-string) "\n")))))
(defun taskrunner-get-gradle-tasks (dir)
"Retrieve the gradle tasks for the project in directory DIR.
This function returns a list of the form:
\(\"GRADLE TASK1\" \"GRADLE TASK2\"...)"
(let ((default-directory dir)
(gradle-tasks '()))
(call-process "gradle" nil (taskrunner--make-task-buff-name "gradle") nil "tasks")
(with-temp-buffer
(set-buffer (taskrunner--make-task-buff-name "gradle"))
(dolist (curr-regex taskrunner-gradle-heading-regexps)
(let ((tasks-retrieved (taskrunner--retrieve-gradle-heading-tasks curr-regex)))
(when tasks-retrieved
(setq gradle-tasks (append gradle-tasks tasks-retrieved))
)))
(kill-current-buffer))
;; Return the tasks acquired
gradle-tasks))
;; In general, the output of 'ant -verbose -p' looks like this:
;; some-java-logging-commands...
;; ...
;; Main targets:
;;
;; main_target1 comment
;; ...
;; main_targetN comment
;; Other targets:
;;
;; other_target1
;; ...
;; other_targetN
;; Sometimes the buffer might end with 'Default target:' and sometimes
;; it might not if there is no default target assigned for project
(defun taskrunner--retrieve-ant-tasks-from-buffer ()
"Retrieve all and tasks from the current buffer.
This function is meant to be used with the output of `ant -verbose -p'.
If you need to retrieve tasks from ant, use the function
`taskrunner-get-ant-tasks' instead of this."
(goto-char (point-min))
(let ((beg (search-forward-regexp "Main targets:\n\n" nil t))
(ant-tasks '()))
(when beg
(narrow-to-region (point-at-bol)
(progn
(search-forward-regexp "Other targets:")
(forward-line -1)
(point-at-eol)))
(cl-map 'list (lambda (elem)
(if (not (string-equal elem ""))
(push (concat "ANT" " " (car (split-string (string-trim elem) " "))) ant-tasks)
))
(split-string (buffer-string) "\n"))
(widen))
;; Look for the 'Other targets' section
(goto-char (point-min))
(setq beg (search-forward-regexp "Other targets:\n\n" nil t))
;; If the section exists, retrieve the tasks in it.
(when beg
(narrow-to-region (point-at-bol)
;; If the ant project has a default target then the last
;; line of the output starts with 'Default target'
;; which is not a task which can be ran but information.
;; Otherwise, the last line is a task
(if (search-forward-regexp "Default target:" nil t)
(progn
(forward-line -1)
(point-at-eol))
(progn
(goto-char (point-max))
(point-at-eol))
))
(cl-map 'list (lambda (elem)
(if (not (string-equal elem ""))
(push (concat "ANT" " " (car (split-string (string-trim elem) " "))) ant-tasks)))
(split-string (buffer-string) "\n")))
(kill-current-buffer)
;; Return the tasks after killing buffer
ant-tasks))
(defun taskrunner-get-ant-tasks (DIR)
"Retrieve the ant tasks for the project in directory DIR.
This function returns a list of the form:
\(\"ANT TASK1\" \"ANT TASK2\"...)"
(let ((default-directory DIR))
(call-process "ant" nil (taskrunner--make-task-buff-name "ant") nil "-verbose" "-p")
(with-temp-buffer
(set-buffer (taskrunner--make-task-buff-name "ant"))
(taskrunner--retrieve-ant-tasks-from-buffer))))
(provide 'taskrunner-java)
;;; taskrunner-java.el ends here