From 241a06226977140874d3f5559e281c543538d4d8 Mon Sep 17 00:00:00 2001 From: jcs090218 Date: Sat, 25 Feb 2023 13:21:38 -0800 Subject: [PATCH 1/5] fix(process): Workaround for arguments that contain whitespaces --- cmds/core/emacs.js | 4 ++-- cmds/core/exec.js | 4 +--- cmds/core/run.js | 6 +----- src/util.js | 21 +++++++++++++++++++-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/cmds/core/emacs.js b/cmds/core/emacs.js index 072c7144..916784d3 100644 --- a/cmds/core/emacs.js +++ b/cmds/core/emacs.js @@ -35,12 +35,12 @@ exports.builder = async (yargs) => { exports.handler = async (argv) => { let _path = UTIL.el_script('core/emacs'); - let default_cmd = ['-Q', '-l', _path]; + let default_cmd = ['emacs', '-Q', '-l', _path]; let rest = process.argv.slice(3); let cmd = default_cmd.concat(rest); UTIL.setup_env(); - let proc = child_process.spawn('emacs', cmd, { stdio: 'inherit' }); + let proc = child_process.spawn(UTIL.cli_args(cmd), { stdio: 'inherit', shell: true }); proc.on('close', function (code) { if (code == 0) return; diff --git a/cmds/core/exec.js b/cmds/core/exec.js index 7f92554a..405f3532 100644 --- a/cmds/core/exec.js +++ b/cmds/core/exec.js @@ -49,9 +49,7 @@ exports.handler = async (argv) => { process.env.PATH = fs.readFileSync(epf, 'utf8'); process.env.EMACSLOADPATH = fs.readFileSync(lpf, 'utf8');; - let program = cmd[0]; - let rest = cmd.slice(1); - let proc = child_process.spawn(program, rest, { stdio: 'inherit', shell: true }); + let proc = child_process.spawn(UTIL.cli_args(cmd), { stdio: 'inherit', shell: true }); proc.on('close', function (code) { if (code == 0) return; diff --git a/cmds/core/run.js b/cmds/core/run.js index dcf7eebc..105c145e 100644 --- a/cmds/core/run.js +++ b/cmds/core/run.js @@ -65,11 +65,7 @@ function startCommand(commands, count) { let command = commands[count]; console.log('[RUN]: ' + command); - let splitted = command.split(' '); - - let program = splitted[0]; - let rest = splitted.slice(1); - let proc = child_process.spawn(program, rest, { stdio: 'inherit', shell: true }); + let proc = child_process.spawn(command, { stdio: 'inherit', shell: true }); proc.on('close', function (code) { if (code == 0) { diff --git a/src/util.js b/src/util.js index feb4bfdf..d5c26b6f 100644 --- a/src/util.js +++ b/src/util.js @@ -22,6 +22,22 @@ const path = require('path'); const child_process = require("child_process"); +/** + * Form CLI arguments into a single string. + * @param { Array } argv - Argument vector. + */ +function cli_args(argv) { + let result = ''; + argv.forEach(function (element) { + // XXX: We wrap double quotes if the string contains spaces + if (/\s/g.test(element)) { + element = '\"' + element + '\"'; + } + result += ' ' + element; + }); + return result; +} + /* * Remove `undefined` item from the array * @param { Array } arr - target array @@ -118,7 +134,7 @@ async function e_call(argv, script, ...args) { return new Promise(resolve => { let _path = el_script(script); - let cmd_base = ['-Q', '--script', _path]; + let cmd_base = ['emacs', '-Q', '--script', _path]; let cmd_args = args.flat(); let cmd_global = _global_options(argv).flat(); let cmd = cmd_base.concat(cmd_args).concat(cmd_global); @@ -133,7 +149,7 @@ async function e_call(argv, script, ...args) { console.log('[DEBUG] emacs ' + cmd.join(' ')); setup_env(); - let proc = child_process.spawn('emacs', cmd, { stdio: 'inherit' }); + let proc = child_process.spawn(cli_args(cmd), { stdio: 'inherit', shell: true }); proc.on('close', function (code) { if (code == 0) { @@ -148,6 +164,7 @@ async function e_call(argv, script, ...args) { /* * Module Exports */ +module.exports.cli_args = cli_args; module.exports.plugin_dir = plugin_dir; module.exports.def_flag = def_flag; module.exports.setup_env = setup_env; From d6b4412ef1465306c2cc9b97b61489fe3df4f328 Mon Sep 17 00:00:00 2001 From: jcs090218 Date: Sat, 25 Feb 2023 13:28:52 -0800 Subject: [PATCH 2/5] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 156ebb44..5ae09d15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how * feat: Add capability to search through path (#119) * Support DSL `package-descriptor` (#124) * Resolve the potential symlink to the bash script (#24, #125, and #126) +* Workaround for arguments that contain whitespaces (#128 and #129) ## 0.7.x > Released Sep 08, 2022 From 0c2364471162f825dcdfc3c694f02001dad52a3b Mon Sep 17 00:00:00 2001 From: jcs090218 Date: Sat, 25 Feb 2023 17:03:36 -0800 Subject: [PATCH 3/5] Fix eval command --- .gitignore | 3 +++ cmds/core/eval.js | 38 +++++++++++++++++++++++++++++++++++++- cmds/core/exec.js | 2 ++ lisp/core/eval.el | 17 ++++++++++++----- src/util.js | 8 +++++++- test/commands/local/run.sh | 2 +- 6 files changed, 62 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index f7c2881c..1275f459 100644 --- a/.gitignore +++ b/.gitignore @@ -143,6 +143,9 @@ dist # internal test _test/ +# emacs +emacs_backtrace.txt + # ignore generated files *.elc diff --git a/cmds/core/eval.js b/cmds/core/eval.js index 3f7705d3..9d47674a 100644 --- a/cmds/core/eval.js +++ b/cmds/core/eval.js @@ -19,6 +19,9 @@ "use strict"; +const fs = require('fs'); +const child_process = require("child_process"); + exports.command = ['eval [form]']; exports.desc = 'Evaluate lisp form with a proper PATH'; exports.builder = { @@ -30,5 +33,38 @@ exports.builder = { }; exports.handler = async (argv) => { - await UTIL.e_call(argv, 'core/eval', '\"' + argv.form.replace(/[\\$'"]/g, "\\$&") + '\"'); + // 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)) { + return; + } + + console.log(''); + + let epf = global.EASK_HOMEDIR + 'exec-path'; + let lpf = global.EASK_HOMEDIR + 'load-path'; + + process.env.PATH = fs.readFileSync(epf, 'utf8'); + process.env.EMACSLOADPATH = fs.readFileSync(lpf, 'utf8');; + + let expressions = process.argv.slice(3); + + // XXX: Just replace `form` property, this is combined expression + argv.form = expressions.join(' '); + + let cmd = ['emacs', '--batch', '--eval', argv.form]; + + let proc = child_process.spawn(UTIL.cli_args(cmd), { stdio: 'inherit', shell: true }); + + proc.on('close', function (code) { + if (code == 0) return; + throw 'Exit with code: ' + code; + }); }; + +function escapeDoubleQuotes(str) { + return str.replaceAll('\"', '\\"'); +} diff --git a/cmds/core/exec.js b/cmds/core/exec.js index 405f3532..351b9992 100644 --- a/cmds/core/exec.js +++ b/cmds/core/exec.js @@ -43,6 +43,8 @@ exports.handler = async (argv) => { return; } + console.log(''); + let epf = global.EASK_HOMEDIR + 'exec-path'; let lpf = global.EASK_HOMEDIR + 'load-path'; diff --git a/lisp/core/eval.el b/lisp/core/eval.el index e160cda5..00a53e2a 100644 --- a/lisp/core/eval.el +++ b/lisp/core/eval.el @@ -14,12 +14,19 @@ (file-name-directory (nth 1 (member "-scriptload" command-line-args)))) nil t) -(require 'thingatpt) +(eask-load "core/exec") (eask-start - (let ((form (eask-argv 0))) - (with-temp-buffer - (insert (thing-at-point--read-from-whole-string form)) - (eval-buffer)))) + (eask-defvc< 27 (eask-pkg-init)) ; XXX: remove this after we drop 26.x + (eask-setup-paths) + (ignore-errors (delete-directory eask-homedir t)) ; clean up + + (if-let ((name (eask-argv 0))) + (eask-with-progress + (ansi-green "Exporting environment variables... ") + (eask--export-env) + (ansi-green "done ✓")) + (eask-info "✗ (No expression found)") + (eask-help "core/eval"))) ;;; core/eval.el ends here diff --git a/src/util.js b/src/util.js index d5c26b6f..6777ddc2 100644 --- a/src/util.js +++ b/src/util.js @@ -28,12 +28,18 @@ const child_process = require("child_process"); */ function cli_args(argv) { let result = ''; + let first = true; argv.forEach(function (element) { // XXX: We wrap double quotes if the string contains spaces if (/\s/g.test(element)) { + element = element.replaceAll('\"', '\\"'); // escape double quotes element = '\"' + element + '\"'; } - result += ' ' + element; + if (first) + result += element; + else + result += ' ' + element; + first = false; }); return result; } diff --git a/test/commands/local/run.sh b/test/commands/local/run.sh index e337ee87..62eb32cd 100644 --- a/test/commands/local/run.sh +++ b/test/commands/local/run.sh @@ -57,7 +57,7 @@ eask run test eask run -all # Exection -eask eval '(progn (message "Hello World!~"))' +eask eval '(progn (message \""Hello World!~\""))' # Linter eask lint checkdoc From 7fd6363e9aa20f4af1adf42a5a3cf07810238ff4 Mon Sep 17 00:00:00 2001 From: jcs090218 Date: Sat, 25 Feb 2023 17:04:52 -0800 Subject: [PATCH 4/5] Remove useless function --- cmds/core/eval.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmds/core/eval.js b/cmds/core/eval.js index 9d47674a..4f1c2b67 100644 --- a/cmds/core/eval.js +++ b/cmds/core/eval.js @@ -64,7 +64,3 @@ exports.handler = async (argv) => { throw 'Exit with code: ' + code; }); }; - -function escapeDoubleQuotes(str) { - return str.replaceAll('\"', '\\"'); -} From 5210a4dc9cd3dace3d54340fb438c8a110159307 Mon Sep 17 00:00:00 2001 From: jcs090218 Date: Sat, 25 Feb 2023 17:15:55 -0800 Subject: [PATCH 5/5] change eval test --- test/commands/local/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/local/run.sh b/test/commands/local/run.sh index 62eb32cd..cf69f31a 100644 --- a/test/commands/local/run.sh +++ b/test/commands/local/run.sh @@ -57,7 +57,7 @@ eask run test eask run -all # Exection -eask eval '(progn (message \""Hello World!~\""))' +eask eval "(progn (require 'mini.emacs.pkg.1))" # Linter eask lint checkdoc