diff --git a/CHANGELOG.md b/CHANGELOG.md index c51746bc..24543b51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how * Add command `cat` (#160) * Improve messages while processing package transaction (#164) * Improve messages while task cleaning all (#165) +* Add `clean` option for clean compile environment (#166) ## 0.8.x > Released Mar 08, 2023 diff --git a/cmds/core/compile.js b/cmds/core/compile.js index f27f0c10..39c341c0 100644 --- a/cmds/core/compile.js +++ b/cmds/core/compile.js @@ -26,8 +26,18 @@ exports.builder = yargs => yargs '[names..]', { description: 'specify files to byte-compile', type: 'array', - }); + }) + .options({ + 'clean': { + description: 'clean byte-compile files individually', + alias: 'c', + type: 'boolean', + group: TITLE_CMD_OPTION, + }, + }); exports.handler = async (argv) => { - await UTIL.e_call(argv, 'core/compile', argv.names); + await UTIL.e_call(argv, 'core/compile' + , argv.names + , UTIL.def_flag(argv.clean, '--clean')); }; diff --git a/lisp/_prepare.el b/lisp/_prepare.el index 5d95eab6..a2def249 100644 --- a/lisp/_prepare.el +++ b/lisp/_prepare.el @@ -446,9 +446,12 @@ For arguments FUNC and DEPS, see function `mapc' for more information." (defconst eask-has-colors (getenv "EASK_HASCOLORS") "Return non-nil if terminal support colors.") -(defconst eask-homedir (getenv "EASK_HOMEDIR") ; temporary environment from node +(defconst eask-homedir (getenv "EASK_HOMEDIR") "Eask temporary storage.") +(defconst eask-invocation (getenv "EASK_INVOCATION") + "Eask invocation program.") + ;; ;;; Flags @@ -477,6 +480,7 @@ For arguments FUNC and DEPS, see function `mapc' for more information." (defun eask-allow-error-p () (eask--flag "--allow-error")) ; --allow-error (defun eask-insecure-p () (eask--flag "--insecure")) ; --insecure (defun eask-no-color-p () (eask--flag "--no-color")) ; --no-color +(defun eask-clean-p () (eask--flag "--clean")) ; -c, --clean (defun eask-json-p () (eask--flag "--json")) ; --json (defun eask-number-p () (eask--flag "--number")) ; -n, --number @@ -544,6 +548,7 @@ other scripts internally. See function `eask-call'.") "--log-file" "--elapsed-time" "--no-color" + "--clean" "--json" "--number")) "List of boolean type options.") @@ -564,7 +569,17 @@ other scripts internally. See function `eask-call'.") "Return non-nil if ARG is known internal command." (member arg eask--command-list)) -(defun eask-argv (index) "Return argument value by INDEX." (elt eask-argv index)) +(defun eask-argv (index) + "Return argument value by INDEX." + (elt eask-argv index)) + +(defun eask-argv-out () + "Convert all internal arguments to external arguments. + +Simply remove `--eask' for each option, like `--eask--strict' to `--strict'." + (mapcar (lambda (arg) + (eask-s-replace "--eask" "" arg)) + eask-argv)) (defun eask-args () "Get all arguments except options." diff --git a/lisp/core/compile.el b/lisp/core/compile.el index 73472557..eac65de2 100644 --- a/lisp/core/compile.el +++ b/lisp/core/compile.el @@ -22,7 +22,7 @@ ;; Handle options (add-hook 'eask-before-command-hook (lambda () - (when (eask-strict-p) (setq byte-compile-error-on-warn t)) + (when (eask-strict-p) (setq byte-compile-error-on-warn t)) (when (= eask-verbosity 4) (setq byte-compile-verbose t)))) (defconst eask-compile-log-buffer-name "*Compile-Log*" @@ -32,9 +32,50 @@ "Print `*Compile-Log*' buffer." (when (get-buffer eask-compile-log-buffer-name) (with-current-buffer eask-compile-log-buffer-name - (eask-print-log-buffer) + (if (and (eask-clean-p) (eask-strict-p)) + (eask-error (buffer-string)) ; Exit with error code! + (eask-print-log-buffer)) (eask-msg "")))) +(defun eask--byte-compile-file-external-contetnt (filename cmd) + "Extract result after executing byte-compile the FILENAME. + +The CMD is the command to start a new Emacs session." + (with-temp-buffer + (insert (shell-command-to-string cmd)) + (goto-char (point-min)) + (search-forward filename nil t) + (re-search-forward "[ \t\r\n]" nil t) + (let ((line (string-trim (thing-at-point 'line)))) + (if (and (string-prefix-p "Compiling " line) + (or (string-match-p "... skipped" line) + (string-match-p "... done" line))) + (delete-region (point-min) (line-end-position 1)) + (delete-region (point-min) (point)))) + (when (search-forward "(Total of " nil t) + (goto-char (point-max)) + (delete-region (line-beginning-position -1) (point-max))) + (string-trim (buffer-string)))) + +(defun eask--byte-compile-file-external (filename) + "Byte compile FILENAME with clean environment by opening a new Emacs session." + (let* ((cmd (split-string eask-invocation "\n" t)) + (cmd (format "\"%s\""(mapconcat #'identity cmd "\" \""))) + (args (eask-args)) + (argv (cl-remove-if + (lambda (arg) + (or (string= "--clean" arg) ; prevent infinite call + (member arg args))) ; remove repeated arguments + (eask-argv-out))) + (args (append `(,(eask-command) ,(concat "\"" filename "\"")) argv)) + (args (mapconcat #'identity args " ")) + (cmd (concat cmd " " args)) + (content (eask--byte-compile-file-external-contetnt filename cmd))) + (if (string-empty-p content) + t ; no error, good! + (with-current-buffer (get-buffer-create eask-compile-log-buffer-name) + (insert content))))) + (defun eask--byte-compile-file (filename) "Byte compile FILENAME." ;; *Compile-Log* does not kill itself. Make sure it's clean before we do @@ -45,7 +86,9 @@ (eask-with-progress (unless byte-compile-verbose (format "Compiling %s... " filename)) (eask-with-verbosity 'debug - (setq result (byte-compile-file filename) + (setq result (if (eask-clean-p) + (eask--byte-compile-file-external filename) + (byte-compile-file filename)) result (eq result t))) (if result "done ✓" "skipped ✗")) (eask--print-compile-log) diff --git a/lisp/core/info.el b/lisp/core/info.el index becedff5..ecb00e93 100644 --- a/lisp/core/info.el +++ b/lisp/core/info.el @@ -41,8 +41,10 @@ (ansi-yellow (eask-package-version)) (ansi-cyan (eask-2str (length eask-depends-on))) (ansi-cyan (eask-2str (length eask-depends-on-dev)))) - (eask-msg (eask-package-description)) - (when-let ((url (or (eask-package-desc-url) eask-website-url))) + (unless (string-empty-p (eask-package-description)) + (eask-msg (eask-package-description))) + (when-let* ((url (or (eask-package-desc-url) eask-website-url)) + ((not (string-empty-p url)))) (eask-msg (ansi-cyan url))) (when-let ((keywords (or (eask-package-desc-keywords) eask-keywords))) (eask-msg "") diff --git a/src/env.js b/src/env.js index 2be80b9b..5582a6b4 100644 --- a/src/env.js +++ b/src/env.js @@ -25,10 +25,12 @@ const path = require('path'); global.UTIL = require('./util'); global.IS_PKG = path.basename(process.execPath).startsWith('eask'); -global.GITHUB_ACTIONS = (process.env.GITHUB_WORKSPACE !== undefined); - +/* Environment PATH */ global.EASK_HOMEDIR = os.homedir().replace(/\\/g, '/') + '/.eask/'; -/* Global Variables */ +/* Titles */ global.TITLE_CMD_OPTION = 'Command Options:'; global.TITLE_PROXY_OPTION = 'Proxy Options:'; + +/* CI */ +global.GITHUB_ACTIONS = (process.env.GITHUB_WORKSPACE !== undefined); diff --git a/src/util.js b/src/util.js index ee6bc997..40769d79 100644 --- a/src/util.js +++ b/src/util.js @@ -71,11 +71,23 @@ function def_flag(arg, name, val = undefined) { return ['--eask' + name, val]; } +/** + * Return the invocation program. + * @return This would either be a path or paths with newline. + */ +function _invocation() { + if (IS_PKG) + return execPath; + // The is consist of `node` (executable) + `eask` (script) + return process.argv[0] + '\n' + process.argv[1]; +} + /** * Setup the environment variables so Emacs could receive them. */ function setup_env() { /* Home Directory */ + process.env.EASK_INVOCATION = _invocation(); process.env.EASK_HOMEDIR = EASK_HOMEDIR; if (GITHUB_ACTIONS) { diff --git a/test/commands/local/run.sh b/test/commands/local/run.sh index 0b54dfdd..3030979c 100644 --- a/test/commands/local/run.sh +++ b/test/commands/local/run.sh @@ -52,6 +52,7 @@ eask package # Development eask compile +eask compile --clean eask recipe eask keywords eask run