Ensure exit codes (where applicable) (#82)

* Ensure exit codes

* cleanup a lil'

* lock nix version to nix:2.3.16

* make some requested changes

* save changes to utils.go
This commit is contained in:
AllAwesome497 2022-01-18 12:03:34 -06:00 committed by GitHub
parent 02c7adf7b1
commit a584d8e52b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 112 additions and 55 deletions

View File

@ -16,7 +16,7 @@ jobs:
- run: make test-image
nix_build:
docker:
- image: nixos/nix
- image: nixos/nix:2.3.16
steps:
- checkout
- restore_cache:

View File

@ -37,10 +37,11 @@ func (p Julia) Eval(code string) {
C.eval(cstr)
}
func (p Julia) EvalFile(file string, args []string) {
func (p Julia) EvalFile(file string, args []string) int {
cstr := C.CString(file)
C.eval_file(cstr)
C.free(unsafe.Pointer(cstr))
defer C.free(unsafe.Pointer(cstr))
return int(C.eval_file(cstr))
}
func (p Julia) REPL() {

View File

@ -107,7 +107,7 @@ void cleanup() { jl_atexit_hook(0); }
void eval(const char *str) { jl_eval_string(str); }
void eval_file(const char *path) { exec_program(path); }
int eval_file(const char *path) { return exec_program(path); }
void run_repl() { fancy_repl(); }

View File

@ -49,11 +49,11 @@ func (p Lua) Eval(code string) {
C.pry_eval(ccode)
}
func (p Lua) EvalFile(file string) {
func (p Lua) EvalFile(file string, args []string) int {
cfile := C.CString(file)
defer C.free(unsafe.Pointer(cfile))
C.pry_eval_file(cfile)
return int(C.pry_eval_file(cfile))
}
func (p Lua) REPL() {

View File

@ -13,4 +13,4 @@ void pry_eval(const char *code) { dostring(pry_L, code, "<eval>"); }
void pry_do_repl(void) { dotty(pry_L); }
void pry_eval_file(char *file) { handle_script(pry_L, &file, 0); }
int pry_eval_file(char *file) { return handle_script(pry_L, &file, 0); }

View File

@ -4,7 +4,7 @@ extern lua_State *pry_L;
const char *pry_get_version(void);
void pry_eval(const char *code);
void pry_eval_file(char *file);
int pry_eval_file(char *file);
void pry_do_repl(void);
// from the lua repl lib (lua.c)

View File

@ -1,6 +1,5 @@
const repl = require('repl');
const path = require('path');
const { isatty } = require('tty');
const assets_dir =
process.env.PRYBAR_ASSETS_DIR || path.join(process.cwd(), 'prybar_assets');
/**
@ -13,7 +12,7 @@ const rl = require(path.join(assets_dir, 'nodejs', 'input-sync.js'));
const { runCode, runModule, getRepl } = require(path.join(
assets_dir,
'nodejs',
'module-context-hook.js',
'module-context-hook.js'
));
// imports to builtin modules don't get added to require.cache.
@ -32,7 +31,7 @@ Error.prepareStackTrace = function prepareStackTrace(error, callSites) {
const idx = callSites.findIndex((frame) => frame.getFunctionName() === null);
const domainIndex = callSites.findIndex(
(site) => site.getFileName() === 'domain.js',
(site) => site.getFileName() === 'domain.js'
);
if (domainIndex !== -1 && domainIndex < idx) {
@ -43,7 +42,7 @@ Error.prepareStackTrace = function prepareStackTrace(error, callSites) {
callSites.reverse();
const lowestPrybarFileIndex = callSites.findIndex((site) =>
prybarFilenames.includes(site.getFileName()),
prybarFilenames.includes(site.getFileName())
);
callSites = callSites.slice(0, lowestPrybarFileIndex);
@ -68,18 +67,16 @@ if (!process.env.PRYBAR_QUIET) {
console.log('Node ' + process.version + ' on ' + process.platform);
}
const isTTY = isatty(process.stdin.fd);
// Red errors (if stdout is a TTY)
// Red errors (if stderr is a TTY)
function logError(msg) {
if (isTTY) {
process.stdout.write(`\u001b[0m\u001b[31m${msg}\u001b[0m`);
if (process.stderr.isTTY) {
process.stderr.write(`\u001b[0m\u001b[31m${msg}\u001b[0m`);
} else {
process.stdout.write(msg);
process.stderr.write(msg);
}
if (!msg.endsWith('\n')) {
process.stdout.write('\n');
process.stderr.write('\n');
}
}
@ -99,7 +96,7 @@ function resumeRepl() {
// Clear the line if it has anything on it.
function clearLine() {
if (isTTY && r && r.line) r.clearLine();
if (process.stdout.isTTY && r && r.line) r.clearLine();
}
// Adapted from the internal node repl code just a lot simpler and adds
@ -179,6 +176,10 @@ if (process.env.PRYBAR_CODE) {
runCode(process.env.PRYBAR_CODE, isInterractive);
} catch (err) {
handleError(err);
if (!isInterractive) {
process.exit(1);
}
}
if (isInterractive) {
@ -189,18 +190,26 @@ if (process.env.PRYBAR_CODE) {
console.log(runCode(process.env.PRYBAR_EXP, false));
} catch (err) {
handleError(err);
if (!isInterractive) {
process.exit(1);
}
}
} else if (process.env.PRYBAR_FILE) {
try {
runModule(process.env.PRYBAR_FILE, isInterractive);
} catch (err) {
handleError(err);
if (!isInterractive) {
process.exit(1);
}
}
if (isInterractive) {
if (isTTY) {
if (process.stdout.isTTY && process.stdin.isTTY) {
console.log(
'\u001b[0m\u001b[90mHint: hit control+c anytime to enter REPL.\u001b[0m',
'\u001b[0m\u001b[90mHint: hit control+c anytime to enter REPL.\u001b[0m'
);
}

View File

@ -38,7 +38,7 @@ func (p Python) EvalExpression(code string) string {
return C.GoString(C.pry_eval(ccode, C.Py_eval_input))
}
func (p Python) EvalFile(file string, args []string) {
func (p Python) EvalFile(file string, args []string) int {
handle := C.stdin
cfile := C.CString(file)
defer C.free(unsafe.Pointer(cfile))
@ -53,7 +53,14 @@ func (p Python) EvalFile(file string, args []string) {
argv := C.CString(file + "\x00" + strings.Join(args, "\x00"))
defer C.free(unsafe.Pointer(argv))
C.pry_eval_file(handle, cfile, C.int(len(args)+1), argv)
status := C.pry_eval_file(handle, cfile, C.int(len(args)+1), argv)
// if status is non-zero an error occured.
if status != 0 {
return 1
}
return 0
}
func (p Python) REPLLikeEval(code string) {

View File

@ -1,6 +1,6 @@
#include "pry_python2.h"
void pry_eval_file(FILE *f, const char *file, int argn, const char *argv)
int pry_eval_file(FILE *f, const char *file, int argn, const char *argv)
{
const char *xargv[argn + 1];
const char *ptr = argv;
@ -11,7 +11,7 @@ void pry_eval_file(FILE *f, const char *file, int argn, const char *argv)
}
xargv[argn] = NULL;
PySys_SetArgvEx(argn, xargv, 1);
PyRun_AnyFile(f, file);
return PyRun_AnyFile(f, file);
}
const char *pry_eval(const char *code, int start)

View File

@ -1,5 +1,5 @@
#include <Python.h>
void pry_eval_file(FILE *f, const char *file, int argn, const char *argv);
int pry_eval_file(FILE *f, const char *file, int argn, const char *argv);
const char *pry_eval(const char *code, int start);
void pry_set_prompts(const char *ps1, const char *ps2);

View File

@ -73,7 +73,7 @@ func (p Python) EvalExpression(code string) string {
return C.GoString(C.pry_eval(ccode, C.Py_eval_input))
}
func (p Python) EvalFile(file string, args []string) {
func (p Python) EvalFile(file string, args []string) int {
handle := C.stdin
cfile := C.CString(file)
defer C.free(unsafe.Pointer(cfile))
@ -88,7 +88,15 @@ func (p Python) EvalFile(file string, args []string) {
argv := C.CString(file + "\x00" + strings.Join(args, "\x00"))
defer C.free(unsafe.Pointer(argv))
C.pry_eval_file(handle, cfile, C.int(len(args)+1), argv)
status := (C.pry_eval_file(handle, cfile, C.int(len(args)+1), argv))
// if status is non-zero an error occured.
if status != 0 {
return 1
}
return 0
}
func (p Python) REPLLikeEval(code string) {
@ -104,7 +112,10 @@ func (p Python) loadModule(mod string) {
}
func (p Python) REPL() {
C.pymain_run_interactive_hook()
var exitCode C.int
if C.pymain_run_interactive_hook(&exitCode) != 0 {
os.Exit(int(exitCode))
}
fn := C.CString("<stdin>")
defer C.free(unsafe.Pointer(fn))

View File

@ -1,6 +1,6 @@
#include "pry_python3.h"
void pry_eval_file(FILE *f, const char *file, int argn, const char *argv)
int pry_eval_file(FILE *f, const char *file, int argn, const char *argv)
{
wchar_t *xargv[argn + 1];
const char *ptr = argv;
@ -11,8 +11,8 @@ void pry_eval_file(FILE *f, const char *file, int argn, const char *argv)
}
xargv[argn] = NULL;
PySys_SetArgvEx(argn, xargv, 1);
PyRun_AnyFile(f, file);
return PyRun_AnyFile(f, file);
}
const char *pry_eval(const char *code, int start)
@ -71,34 +71,49 @@ void pry_set_prompts(const char *ps1, const char *ps2)
}
//From python3 sourcecode
void pymain_run_interactive_hook(void)
int
pymain_run_interactive_hook(int *exitcode)
{
PyObject *sys, *hook, *result;
sys = PyImport_ImportModule("sys");
if (sys == NULL)
{
if (sys == NULL) {
goto error;
}
hook = PyObject_GetAttrString(sys, "__interactivehook__");
Py_DECREF(sys);
if (hook == NULL)
{
if (hook == NULL) {
PyErr_Clear();
return;
return 0;
}
if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) {
goto error;
}
result = _PyObject_CallNoArg(hook);
Py_DECREF(hook);
if (result == NULL)
{
if (result == NULL) {
goto error;
}
Py_DECREF(result);
return;
return 0;
error:
PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
PyErr_Print();
return pymain_err_print(exitcode);
}
int
pymain_err_print(int *exitcode_p)
{
int exitcode;
if (_Py_HandleSystemExit(&exitcode)) {
*exitcode_p = exitcode;
return 1;
}
PyErr_Print();
return 0;
}

View File

@ -1,6 +1,8 @@
#include <Python.h>
void pry_eval_file(FILE *f, const char *file, int argn, const char *argv);
int pry_eval_file(FILE *f, const char *file, int argn, const char *argv);
const char *pry_eval(const char *code, int start);
void pry_set_prompts(const char *ps1, const char *ps2);
void pymain_run_interactive_hook(void);
int pymain_run_interactive_hook(int *exitcode);
int pymain_err_print(int *exitcode_p);
PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p);

View File

@ -34,10 +34,10 @@ func (p Ruby) EvalExpression(code string) string {
return C.GoString(res)
}
func (p Ruby) EvalFile(file string, args []string) {
func (p Ruby) EvalFile(file string, args []string) int {
cfile := C.CString(file)
defer C.free(unsafe.Pointer(cfile))
C.pry_eval_file(cfile)
return int(C.pry_eval_file(cfile))
}
func (p Ruby) REPL() {

View File

@ -36,14 +36,16 @@ char *pry_eval(const char *code)
}
}
void pry_eval_file(const char *file)
int pry_eval_file(const char *file)
{
char *options[] = {"ruby", file};
void *node = ruby_options(2, options);
int state;
int state = 0;
if (ruby_executable_node(node, &state))
{
state = ruby_exec_node(node);
}
return state;
}

View File

@ -4,5 +4,5 @@
void pry_open();
const char *pry_ruby_version();
char *pry_eval(const char *code);
void pry_eval_file(const char *file);
int pry_eval_file(const char *file);

View File

@ -63,7 +63,7 @@ func (p *Tcl) eval(code string) string {
return ""
}
func (p *Tcl) EvalFile(file string, args []string) {
func (p *Tcl) EvalFile(file string, args []string) int {
cfile := C.CString(file)
defer C.free(unsafe.Pointer(cfile))
@ -72,7 +72,10 @@ func (p *Tcl) EvalFile(file string, args []string) {
if status != C.TCL_OK {
errstr := C.GoString(C.Tcl_GetStringResult(p.interp))
fmt.Fprintf(os.Stderr, "error: %s\n", errstr)
return int(status)
}
return 0
}
func (p *Tcl) Eval(code string) {
@ -86,4 +89,5 @@ func (p *Tcl) EvalExpression(code string) string {
func (p *Tcl) Close() {
C.Tcl_Finalize()
}
var Instance = &Tcl{}

View File

@ -25,7 +25,7 @@ type PluginEvalExpression interface {
type PluginEvalFile interface {
PluginBase
EvalFile(file string, args []string)
EvalFile(file string, args []string) int
}
type PluginREPL interface {
@ -80,16 +80,17 @@ func (lang Language) REPLLikeEval(code string) {
}
}
func (lang Language) EvalFile(file string, args []string) {
func (lang Language) EvalFile(file string, args []string) int {
pef, ok := lang.ptr.(PluginEvalFile)
if ok {
pef.EvalFile(file, args)
return pef.EvalFile(file, args)
} else {
dat, err := ioutil.ReadFile(file)
if err != nil {
panic(err)
}
lang.Eval(string(dat))
return 0
}
}

View File

@ -58,12 +58,17 @@ func DoCli(p PluginBase) {
if config.Exp != "" {
lang.EvalAndTryToPrint(config.Exp)
}
if len(config.Args) > 0 {
if _, err := os.Stat(config.Args[0]); os.IsNotExist(err) {
fmt.Println("No such file:", config.Args[0])
os.Exit(2)
} else {
lang.EvalFile(config.Args[0], config.Args[1:])
exitCode := lang.EvalFile(config.Args[0], config.Args[1:])
// TODO: Maybe log if exitCode is non-zero and interractive is true?
if exitCode != 0 && !config.Interactive && !config.OurInteractive {
os.Exit(exitCode)
}
}
}