forked from emacs-taskrunner/emacs-taskrunner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtaskrunner-web.el
144 lines (127 loc) · 5.49 KB
/
taskrunner-web.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
;;; taskrunner-web.el --- Provide functions to retrieve tasks for web build systems-*- lexical-binding: t; -*-
;; Copyright (C) 2019 Yavor Konstantinov
;;; Commentary:
;; This file adds support for taskrunners which are mainly used for
;; javascript/web projects.
;; Support included for:
;; - yarn/npm
;; - gulp
;; - grunt
;; - jake
;;; Code:
;;;; Required
(require 'json)
(require 'subr-x)
(require 'cl-lib)
;;;; Variables
(defcustom taskrunner-preferred-js-package-manager nil
"The preferred package manager to be used for tasks from package.json.
The package manager name should be a string which can be either `npm' or `yarn'.
If its value is nil then the package manager to be used is determined by the presence
of either a `yarn.lock' or `package-lock.json'. If none are present and this
variable is nil then `npm' is used as default."
:type 'string
:options '("npm" "yarn")
:group 'taskrunner)
(defconst taskrunner--js-gulp-tasks-command "gulp --tasks-simple"
"Command used to retrieve the tasks for Gulp.")
;;;; 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")
(defun taskrunner--yarn-or-npm (DIR)
"Detect if the current project in directory DIR is using `yarn' or `npm'.
If `taskrunner-preferred-js-package-manager' is not nil then its value is used.
Otherwise, if `yarn.lock' is present then yarn is used. If `package-lock.json'
is present then NPM is used. If none are present and
`taskrunner-preferred-js-package-manager' is nil then the default is `npm'."
(let ((dir-files (directory-files DIR)))
(cond
((member "yarn.lock" dir-files)
"YARN")
((member "package-lock.json" dir-files)
"NPM")
((stringp taskrunner-preferred-js-package-manager)
(upcase taskrunner-preferred-js-package-manager))
;; Default if no files are present and the preferred package manager is
;; not set
(t
"NPM"))))
(defun taskrunner-get-package-json-tasks (DIR)
"Retrieve all tasks in the scripts section of the package.json file in DIR.
This function returns a list of the form:
\(\PM TASK1\" \"PM TASK2\"...)
where PM is the package manager used(yarn or npm)."
(let* ((package-path (expand-file-name "package.json" DIR))
(package-json-scripts (alist-get 'scripts (json-read-file package-path)))
(task-prefix (taskrunner--yarn-or-npm DIR))
(tasks))
(when package-json-scripts
(setq tasks (cl-map 'list (lambda (elem)
(concat task-prefix " " (symbol-name (car elem))))
package-json-scripts)))
tasks))
(defun taskrunner-get-gulp-tasks (DIR)
"Retrieve the gulp tasks for the project in directory DIR.
This function returns a list of the form:
\(\"GULP TASK1\" \"GULP TASK2\"...)"
(let ((default-directory DIR))
(butlast (cl-map 'list (lambda (elem)
(concat "GULP" " " elem))
(split-string (shell-command-to-string taskrunner--js-gulp-tasks-command) "\n")))))
(defun taskrunner--get-grunt-tasks-from-buffer ()
"Retrieve the grunt tasks from the current buffer and return them as a list.
This function is not meant to be used externally. Use
`taskrunner--get-grunt-tasks' instead."
(goto-char (point-min))
(let ((beg (re-search-forward "Available tasks.+\n" nil t))
;; The end of the region is simply an empty line
(end (re-search-forward "^$" nil t)))
(when beg
(narrow-to-region beg end)
(cl-map 'list (lambda (elem)
(concat "GRUNT" " " (car (split-string (string-trim elem) " "))))
(split-string (buffer-string) "\n")))))
(defun taskrunner-get-grunt-tasks (DIR)
"Retrieve the grunt tasks for the project in directory DIR.
This function returns a list of the form:
\(\"GRUNT TASK1\" \"GRUNT TASK2\"...)"
(let ((default-directory DIR)
(tasks))
(call-process "grunt" nil (taskrunner--make-task-buff-name "grunt") nil "--help")
(with-temp-buffer
(set-buffer (taskrunner--make-task-buff-name "grunt"))
(setq tasks (taskrunner--get-grunt-tasks-from-buffer))
(kill-current-buffer))
(butlast tasks)))
(defun taskrunner--get-jake-tasks-from-buffer ()
"Retrieve the rake tasks from the current buffer.
This function returns a list of the form:
\(\"JAKE TASK1\" \"JAKE TASK2\"...)"
(goto-char (point-min))
(taskrunner--narrow-to-line)
(if (not (string-match-p ".+aborted\." (buffer-string)))
(progn
(widen)
(goto-char (point-min))
(let ((jake-tasks '()))
(while (search-forward-regexp "^jake[[:space:]]+" nil t)
(taskrunner--narrow-to-line)
(push (concat "JAKE" " " (cadr (split-string (buffer-string) " " t))) jake-tasks)
(widen))
(kill-current-buffer)
jake-tasks))
nil))
(defun taskrunner-get-jake-tasks (DIR)
"Retrieve the ant tasks for the project in directory DIR.
This function returns a list of the form:
\(\"JAKE TASK1\" \"JAKE TASK2\"...)"
(let ((default-directory DIR))
(call-process "jake" nil (taskrunner--make-task-buff-name "jake") nil "-T")
(with-temp-buffer
(set-buffer (taskrunner--make-task-buff-name "jake"))
(taskrunner--get-jake-tasks-from-buffer))))
(provide 'taskrunner-web)
;;; taskrunner-web.el ends here