From 34941548099f1df9cd21d6a21ea3d546d22904ce Mon Sep 17 00:00:00 2001 From: Jen-Chieh Shen Date: Sun, 12 Mar 2023 12:38:16 -0700 Subject: [PATCH] feat(special): Allow few commands' execution without any Eask-file (#159) * feat(special): Allow some commands' execution without Eask-file * changelog * Don't delete homedir * comment * add mark * use slash * Add doc about slash --- CHANGELOG.md | 1 + cmds/core/eval.js | 9 +-- cmds/core/exec.js | 9 +-- cmds/core/run.js | 7 +- .../en/Getting Started/Advanced Usage.md | 24 +++++- lisp/_prepare.el | 74 +++++++++++-------- src/util.js | 3 + 7 files changed, 77 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1fb9d66..6dbeeb5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how * Add command to generate LICENSE file (#155) * Add new DSLs `author` and `license` (#156) * Add license linter (#157) +* Allow few commands' execution without any Eask-file (#159) ## 0.8.x > Released Mar 08, 2023 diff --git a/cmds/core/eval.js b/cmds/core/eval.js index 859c73f7..78af9d4a 100644 --- a/cmds/core/eval.js +++ b/cmds/core/eval.js @@ -34,19 +34,16 @@ exports.builder = { }; exports.handler = async (argv) => { - // setup environment, so Emacs can receive it - process.env.EASK_HOMEDIR = global.EASK_HOMEDIR; - await UTIL.e_call(argv, 'core/eval', argv.form); - if (!fs.existsSync(global.EASK_HOMEDIR)) { + if (!fs.existsSync(EASK_HOMEDIR)) { return; } console.log(''); - let epf = global.EASK_HOMEDIR + 'exec-path'; - let lpf = global.EASK_HOMEDIR + 'load-path'; + let epf = EASK_HOMEDIR + 'exec-path'; + let lpf = EASK_HOMEDIR + 'load-path'; process.env.PATH = fs.readFileSync(epf, 'utf8'); process.env.EMACSLOADPATH = fs.readFileSync(lpf, 'utf8');; diff --git a/cmds/core/exec.js b/cmds/core/exec.js index 351b9992..d43d814b 100644 --- a/cmds/core/exec.js +++ b/cmds/core/exec.js @@ -32,21 +32,18 @@ exports.builder = async (yargs) => { }; exports.handler = async (argv) => { - // setup environment, so Emacs can receive it - process.env.EASK_HOMEDIR = global.EASK_HOMEDIR; - let cmd = process.argv.slice(3); await UTIL.e_call(argv, 'core/exec', '--', cmd); - if (!fs.existsSync(global.EASK_HOMEDIR)) { + if (!fs.existsSync(EASK_HOMEDIR)) { return; } console.log(''); - let epf = global.EASK_HOMEDIR + 'exec-path'; - let lpf = global.EASK_HOMEDIR + 'load-path'; + let epf = EASK_HOMEDIR + 'exec-path'; + let lpf = EASK_HOMEDIR + 'load-path'; process.env.PATH = fs.readFileSync(epf, 'utf8'); process.env.EMACSLOADPATH = fs.readFileSync(lpf, 'utf8');; diff --git a/cmds/core/run.js b/cmds/core/run.js index 66106b3f..1379d42c 100644 --- a/cmds/core/run.js +++ b/cmds/core/run.js @@ -34,16 +34,13 @@ exports.builder = { }; exports.handler = async (argv) => { - // setup environment, so Emacs can receive it - process.env.EASK_HOMEDIR = global.EASK_HOMEDIR; - await UTIL.e_call(argv, 'core/run', argv.names); - if (!fs.existsSync(global.EASK_HOMEDIR)) { + if (!fs.existsSync(EASK_HOMEDIR)) { return; } - let run = global.EASK_HOMEDIR + 'run'; + let run = EASK_HOMEDIR + 'run'; // this contain the full command! let instruction = fs.readFileSync(run, 'utf8'); diff --git a/docs/content/en/Getting Started/Advanced Usage.md b/docs/content/en/Getting Started/Advanced Usage.md index 928ee8a1..1ba00fc2 100644 --- a/docs/content/en/Getting Started/Advanced Usage.md +++ b/docs/content/en/Getting Started/Advanced Usage.md @@ -32,7 +32,29 @@ This is also equivalent to option `--strict`: $ eask compile [FILES..] --strict ``` -Or hooks run on every command: +Or hooks that run on every command: * `eask-before-command-hook` * `eask-after-command-hook` + +```elisp +(add-hook 'eask-before-command-hook + (lambda () + (message "%s" (eask-command)))) ; print the current command +``` + +For subcommands that contain spaces, will concatenate with `/`: + +```sh +$ eask lint checkdoc # lint/checkdoc +$ eask generate license # generate/license +``` + +therefore, + +```elisp +(add-hook 'eask-before-lint/checkdoc-hook + (lambda () + ;; do stuff before checkdoc linting... + )) +``` diff --git a/lisp/_prepare.el b/lisp/_prepare.el index dbe03af5..90803275 100644 --- a/lisp/_prepare.el +++ b/lisp/_prepare.el @@ -67,22 +67,24 @@ "What's the current command? If the command is with subcommand, it will return command with concatenate with -dash separator. For example, the following: +slash separator. For example, the following: $ eask lint checkdoc [FILES..] -will return `lint-checkdoc' with a dash between two subcommands." +will return `lint/checkdoc' with a dash between two subcommands." (let* ((script-dir (file-name-directory eask--script)) (script-file (file-name-sans-extension (file-name-nondirectory eask--script))) (module-name (eask-s-replace eask-lisp-root "" script-dir)) - (module-name (eask-s-replace "/" "" module-name))) - ;; Ignore if it's inside core module - (if (member module-name '("core" "checker")) script-file - (concat module-name "-" script-file)))) + (module-names (split-string module-name "/" t))) + ;; Make certain commands the root command; e.g. `core', `checker', etc. + (if (member (nth 0 module-names) '("core" "checker")) script-file + (mapconcat #'identity (append module-names + (list script-file)) + "/")))) (defun eask-special-p () "Return t if the command that can be run without Eask-file existence." - (member (eask-command) '("init-cask" "keywords"))) + (member (eask-command) '("init/cask" "keywords" "generate/license"))) (defun eask-checker-p () "Return t if running Eask as the checker." @@ -692,13 +694,24 @@ This uses function `locate-dominating-file' to look up directory tree." (defmacro eask--with-hooks (&rest body) "Execute BODY with before/after hooks." (declare (indent 0) (debug t)) - `(progn + `(let* ((command (eask-command)) + (before (concat "eask-before-" command "-hook")) + (after (concat "eask-after-" command "-hook"))) (run-hooks 'eask-before-command-hook) - (run-hooks (intern (concat "eask-before-" (eask-command) "-hook"))) + (run-hooks (intern before)) ,@body - (run-hooks (intern (concat "eask-after-" (eask-command) "-hook"))) + (run-hooks (intern after)) (run-hooks 'eask-after-command-hook))) +(defmacro eask--setup-home (dir &rest body) + "Set up config directory in DIR, then execute BODY." + (declare (indent 1) (debug t)) + `(let* ((user-emacs-directory (expand-file-name (concat ".eask/" emacs-version "/") ,dir)) + (package-user-dir (expand-file-name "elpa" user-emacs-directory)) + (user-init-file (locate-user-emacs-file "init.el")) + (custom-file (locate-user-emacs-file "custom.el"))) + ,@body)) + (defmacro eask-start (&rest body) "Execute BODY with workspace setup." (declare (indent 0) (debug t)) @@ -709,15 +722,18 @@ This uses function `locate-dominating-file' to look up directory tree." (eask--handle-global-options) (eask--print-env-info) (cond + ((eask-special-p) ; Commands without Eask-file needed + (ignore-errors (delete-directory eask-homedir t)) ; clean up + (eask--setup-home (concat eask-homedir "../") ; `/home/user/', escape `.eask' + (ignore-errors (make-directory package-user-dir t)) + (eask--with-hooks ,@body))) ((eask-global-p) - (let* ((special (eask-special-p)) - (inhibit-config (or special (eask-quick-p)))) - (unless special - ;; We accept Eask-file in global scope, but it shouldn't be used - ;; for the sandbox. - (if (eask-file-try-load "./") - (eask-msg "✓ Loading config Eask file in %s... done!" eask-file) - (eask-msg "✗ Loading config Eask file... missing!"))) + (let ((inhibit-config (eask-quick-p))) + ;; We accept Eask-file in global scope, but it shouldn't be used + ;; for the sandbox. + (if (eask-file-try-load "./") + (eask-msg "✓ Loading config Eask file in %s... done!" eask-file) + (eask-msg "✗ Loading config Eask file... missing!")) (message "") (package-activate-all) (eask-with-progress @@ -730,24 +746,18 @@ This uses function `locate-dominating-file' to look up directory tree." (ansi-green (if inhibit-config "skipped ✗" "done ✓"))) (eask--with-hooks ,@body))) (t - (let* ((user-emacs-directory (expand-file-name (concat ".eask/" emacs-version "/"))) - (package-user-dir (expand-file-name "elpa" user-emacs-directory)) - (eask--first-init-p (not (file-directory-p user-emacs-directory))) - (user-init-file (locate-user-emacs-file "init.el")) - (custom-file (locate-user-emacs-file "custom.el")) - (special (eask-special-p))) - (unless special + (eask--setup-home nil ; `nil' is the `default-directory' + (let ((eask--first-init-p (not (file-directory-p user-emacs-directory)))) (if (eask-file-try-load "./") (eask-msg "✓ Loading Eask file in %s... done!" eask-file) (eask-msg "✗ Loading Eask file... missing!") - (eask-help "core/init"))) - (when (or special eask-file) - (message "") - (package-activate-all) - (unless special + (eask-help "core/init")) + (when eask-file + (message "") + (package-activate-all) (ignore-errors (make-directory package-user-dir t)) - (eask--silent (eask-setup-paths))) - (eask--with-hooks ,@body))))))))) + (eask--silent (eask-setup-paths)) + (eask--with-hooks ,@body)))))))))) ;; ;;; Eask file diff --git a/src/util.js b/src/util.js index c1b1f506..ee6bc997 100644 --- a/src/util.js +++ b/src/util.js @@ -75,6 +75,9 @@ function def_flag(arg, name, val = undefined) { * Setup the environment variables so Emacs could receive them. */ function setup_env() { + /* Home Directory */ + process.env.EASK_HOMEDIR = EASK_HOMEDIR; + if (GITHUB_ACTIONS) { /* XXX: isTTY flag will always be undefined in GitHub Actions; we will have * explicitly set environment variables.