-
Notifications
You must be signed in to change notification settings - Fork 17
/
Eldev
177 lines (155 loc) · 8.93 KB
/
Eldev
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
; -*- mode: emacs-lisp; lexical-binding: t -*-
(setf eldev-files-to-package `(:or ,eldev-files-to-package '("./bin" "!./bin/**/*.in" "!./bin/**/*.part")))
(setf eldev-standard-excludes `(:or ,eldev-standard-excludes
;; Avoid including files in test "projects".
(eldev-pcase-exhaustive eldev-test-type
(`main "./test/*/")
(`integration '("./test/" "!./test/integration"))
(`all '("./test/*/" "!./test/integration")))
"./webinstall"
"./htmldoc"))
;; I don't want to "fix" docstrings, especially since they are mostly meant to be printed
;; to console in this project.
(with-eval-after-load 'bytecomp
(setf byte-compile-warnings '(not docstrings)))
(defvar eldev-test-type 'main)
(eldev-defoption eldev-test-selection (type)
"Select tests to run; type can be `main', `integration' or `all'"
:options (-T --test-type)
:for-command test
:value TYPE
:default-value eldev-test-type
(unless (memq (intern type) '(main integration all))
(signal 'eldev-wrong-option-usage `("unknown test type `%s'" ,type)))
(setf eldev-test-type (intern type)))
(eldev-defcommand eldev-test-all (&rest parameters)
"Same as `test --test-type=all'."
:custom-parsing t
:category testing
(let ((parsed (eldev-parse-command-line parameters :command 'test-all)))
(eldev-test-selection "all")
(apply #'eldev-test (plist-get parsed :without-options))))
(eldev-defcommand eldev-test-integration (&rest parameters)
"Same as `test --test-type=integration'."
:custom-parsing t
:category testing
(let ((parsed (eldev-parse-command-line parameters :command 'test-integration)))
(eldev-test-selection "integration")
(apply #'eldev-test (plist-get parsed :without-options))))
(eldev-inherit-options 'test-all 'test (lambda (_option handler) (not (eq handler #'eldev-test-selection))))
(eldev-inherit-options 'test-integration 'test-all)
(add-hook 'eldev-test-hook
(lambda ()
(eldev-verbose "Using Eldev tests of type `%s'" eldev-test-type)
(eldev-print "Eldev tests are fairly slow, since they spawn lots of child processes")))
(add-hook 'eldev-executing-command-hook
(lambda (command)
(unless (eq command 'test)
;; So that e.g. byte-compilation works on all tests.
(setf eldev-test-type 'all))))
(eldev-defbuilder eldev-builder-preprocess-.in (source target)
:short-name "SUBST"
:message source-and-target
:source-files "*.in"
:targets (".in" -> "")
:collect ":default"
:define-cleaner (eldev-cleaner-preprocessed
"Delete results of preprocessing `.in' files. This is specific
to Eldev itself."
:aliases prep)
(let ((modes (file-modes target)))
(eldev-substitute source target)
(when (or modes (string-prefix-p "bin/" target))
(set-file-modes target (or modes #o755)))))
(eldev-defcleaner eldev-cleaner-test-caches ()
"Delete `.eldev' directories in test projects. This is specific
to Eldev itself."
(let (directories)
(dolist (project (directory-files "test"))
(when (and (not (member project '("." ".." ".testroot"))) (file-directory-p (expand-file-name project "test")))
(push (expand-file-name eldev-cache-dir (expand-file-name project "test")) directories)))
directories))
(setf eldev-formatted-project-name "Eldev")
(setf eldev-release-post-release-commit-message "Post-release version bump."
eldev-release-post-release-commit (lambda (version)
(let ((eldev-release-min-version-size 3))
(eldev-release-next-snapshot-version-unless-already-snapshot version))))
(defun eldev--require-future-doc-merged (_version)
(eldev-call-process (eldev-git-executable)
`("for-each-ref" "--no-merged=origin/master" "--format" "%(refname)")
:die-on-error t
;; Catch both local and remote branches. Need to push before releasing.
(when (re-search-forward (rx bol (| "refs/heads/future-doc" "refs/remotes/origin/future-doc") eol) nil t)
(eldev-release-maybe-fail (eldev-format-message "branch `future-doc' is not merged into `origin/master'")))))
;; Insert after after `eldev-release-validate-vcs'.
(push 'eldev--require-future-doc-merged (cdr (memq 'eldev-release-validate-vcs eldev-release-validators )))
(defmacro eldev--install-self-error (error directory format-string &rest arguments)
`(signal 'eldev-error (append (unless (file-writable-p ,directory) '(:hint "You probably need to log in as root"))
(list ,format-string ,@arguments (error-message-string ,error)))))
(eldev-defcommand eldev-install-self (&rest parameters)
"Install Eldev. You only need this command if you want to
install from sources (clone of Git repository). Should probably
be executed via `install.sh'."
:parameters "DIRECTORY"
(unless parameters
(eldev-error "Missing target directory")
(when (boundp 'eldev--install-sh)
(eldev-error "Run as `./install.sh DIRECTORY'"))
(eldev-print "Suggested directories:")
(dolist (directory '("~/bin" "~/.bin" "~/local/bin" "~/.local/bin" "/usr/local/bin" "/usr/bin"))
(when (eldev-directory-in-exec-path directory)
(eldev-print " %s" directory)))
(eldev-print "\nIf you use a different directory, make sure to add it to `PATH'\nenvironment variable.")
(signal 'eldev-quit 1))
(let ((directory (car parameters))
(shell-script-name (eldev--shell-script-name)))
(if (file-exists-p directory)
(unless (file-directory-p directory)
(signal 'eldev-error `("File `%s' exists, but is not a directory" ,directory)))
(if (eldev-y-or-n-p (eldev-format-message "Directory `%s' doesn't exist; attempt to create it? " directory))
(condition-case error
(make-directory directory t)
(error (eldev--install-self-error error (file-name-directory directory) "When creating directory `%s': %s" directory)))
(signal 'eldev-error `("Installation aborted"))))
(when (file-exists-p (expand-file-name shell-script-name directory))
(signal 'eldev-error `("File `%s' already exists in directory `%s'" ,shell-script-name ,directory)))
;; Unless verbosity level is set explicitly, make it `quiet' for
;; building process.
(let ((eldev-verbosity-level (or eldev-verbosity-level 'quiet)))
(eldev-build ":package"))
(condition-case error
(copy-file (format "bin/%s" shell-script-name)
(file-name-as-directory directory))
(error (eldev--install-self-error error (file-name-as-directory directory) "When copying file `eldev' to directory `%s': %s" directory)))
;; Several duplicates with bootstrapping code, but I think it's
;; one of those rare cases where this is fine.
(let* ((eldev--emacs-version (format "%s.%s" emacs-major-version emacs-minor-version))
(package-user-dir (expand-file-name "bootstrap" (expand-file-name eldev--emacs-version (eldev-global-cache-dir)))))
(eldev-install-package-file (expand-file-name (format "dist/eldev-%s.tar" (eldev-message-version (eldev-package-descriptor))))))
(eldev-print "Installation complete%s"
(if (eldev-directory-in-exec-path directory)
"; you can execute `eldev' now"
(format "\nDon't forget to add `%s' to `PATH' environment variable" directory)))))
;; Might want to convert this to a builder later.
(eldev-defcommand eldev-build-documentation (&rest parameters)
"Generate documentation HTML from Asciidoctor source."
:command documentation
:aliases (doc html-doc)
:category building
(when parameters
(signal 'eldev-wrong-command-usage `(t "Unexpected command parameters")))
(eldev-call-process "asciidoctor" `("--backend" "html5"
"--destination-dir" "htmldoc"
"--out-file" "index.html"
;; It seems to treat everything too lightly, so order it to fail on
;; anything even remotely potentially problematic.
"--warnings" "--failure-level" "INFO"
,@(pcase eldev-verbosity-level
(`quiet '("--quiet"))
(`verbose '("--verbose"))
(`trace '("--verbose")))
,@(when debug-on-error '("--trace"))
"doc/README.adoc")
:trace-command-line t
:forward-output t
:die-on-error t))