diff --git a/packages/lde-core/src/package/run.lua b/packages/lde-core/src/package/run.lua index 2cd2fd3..63b4636 100644 --- a/packages/lde-core/src/package/run.lua +++ b/packages/lde-core/src/package/run.lua @@ -69,7 +69,7 @@ local function runFileWithLuaCLI(package, scriptPath, args, vars, engine, cwd) if vars then for k, v in pairs(vars) do env[k] = v end end local code, _, stderr = process.exec(engine, { scriptPath }, { cwd = cwd, env = env, stdout = "inherit", stderr = "inherit" }) - return code == 0 or nil, stderr + return code == 0, stderr or "Script exited with a non-zero exit code" end ---@param package lde.Package @@ -84,7 +84,7 @@ local function runStringWithLuaCLI(package, code, args, vars, engine, cwd) if vars then for k, v in pairs(vars) do env[k] = v end end local exitCode, _, stderr = process.exec(engine, { "-e", code, unpack(args or {}) }, { cwd = cwd, env = env, stdout = "inherit", stderr = "inherit" }) - return exitCode == 0 or nil, stderr + return exitCode == 0, stderr or "Script exited with a non-zero exit code" end ---@param package lde.Package @@ -115,18 +115,13 @@ local function runFile(package, scriptPath, args, vars, cwd, profile, flamegraph cwd = cwd or package:getDir() local engine = config.engine or "lde" - local ok, err if engine == "lde" or engine == "lpm" --[[ compat ]] then - ok, err = runFileWithLDE(package, scriptPath, args, vars, cwd, profile, flamegraph) - else - if profile or flamegraph then - return nil, "Profiling is only supported when engine is 'lde'" - end - - ok, err = runFileWithLuaCLI(package, scriptPath, args, vars, engine, cwd) + return runFileWithLDE(package, scriptPath, args, vars, cwd, profile, flamegraph) end - - return ok or nil, err or "Script exited with a non-zero exit code" + if profile or flamegraph then + return nil, "Profiling is only supported when engine is 'lde'" + end + return runFileWithLuaCLI(package, scriptPath, args, vars, engine, cwd) end ---@param package lde.Package @@ -142,14 +137,10 @@ local function runString(package, code, args, vars, cwd) cwd = cwd or package:getDir() local engine = config.engine or "lde" - local ok, err if engine == "lde" or engine == "lpm" --[[ compat ]] then - ok, err = runStringWithLDE(package, code, args, vars, cwd) - else - ok, err = runStringWithLuaCLI(package, code, args, vars, engine, cwd) + return runStringWithLDE(package, code, args, vars, cwd) end - - return ok or nil, err or "Script exited with a non-zero exit code" + return runStringWithLuaCLI(package, code, args, vars, engine, cwd) end return { runFile = runFile, runString = runString, getLuaPaths = getLuaPathsForPackage } diff --git a/packages/lde-core/src/runtime.lua b/packages/lde-core/src/runtime.lua index a47c41f..4f46da6 100644 --- a/packages/lde-core/src/runtime.lua +++ b/packages/lde-core/src/runtime.lua @@ -301,59 +301,62 @@ local function executeWith(compile, opts, scriptName) local originalTmpname = os.tmpname os.tmpname = env.tmpfile - local ok, result = pcall(function() - package.path = opts.packagePath or oldPath - package.cpath = opts.packageCPath or oldCPath - - local stopProfiler, profilerErr - if opts.profile or opts.flamegraph then - stopProfiler, profilerErr = startProfiler(PROFILER_MS_PER_SAMPLE, scriptName) - if not stopProfiler then - error("Failed to start profiler: " .. tostring(profilerErr)) - end + package.path = opts.packagePath or oldPath + package.cpath = opts.packageCPath or oldCPath + + local stopProfiler + if opts.profile or opts.flamegraph then + local profilerErr + stopProfiler, profilerErr = startProfiler(PROFILER_MS_PER_SAMPLE, scriptName) + if not stopProfiler then + for k, v in pairs(oldEnvVars) do env.set(k, v) end + if oldCwd then env.chdir(oldCwd) end + ffi.cdef = originalCdef + os.tmpname = originalTmpname + restore(package.loaded, savedLoaded) + restore(package.preload, savedPreload) + package.loaders = oldLoaders + package.path, package.cpath = oldPath, oldCPath + return false, "Failed to start profiler: " .. tostring(profilerErr) end + end - local a, b, c, d, e, f - local runOk, runErr = xpcall(function() - if opts.args then - arg = opts.args - arg[0] = scriptName - a, b, c, d, e, f = chunk(unpack(opts.args)) - else - a, b, c, d, e, f = chunk() - end - end, function(err) return err end) - - if stopProfiler then - local counts, vmstates, total, stacks = stopProfiler() - if opts.profile and lde.verbose then - printProfileReport(counts, vmstates, total, env.cwd(), PROFILER_MS_PER_SAMPLE) - end - - if opts.flamegraph then - local fgTitle = scriptName and scriptName:match("[^/\\]+$") - local ok, err = lde.flamegraph.write(stacks, total, PROFILER_MS_PER_SAMPLE, opts.flamegraph, fgTitle) - - if lde.verbose then - if ok then - ansi.printf("{cyan}Flamegraph written to %s\n", opts.flamegraph) - else - ansi.printf("{red}Flamegraph error: %s\n", err or "unknown error") - end + local function finishProfiler() + if not stopProfiler then return end + local counts, vmstates, total, stacks = stopProfiler() + stopProfiler = nil + if opts.profile and lde.verbose then + printProfileReport(counts, vmstates, total, env.cwd(), PROFILER_MS_PER_SAMPLE) + end + if opts.flamegraph then + local fgTitle = scriptName and scriptName:match("[^/\\]+$") + local ok, err = lde.flamegraph.write(stacks, total, PROFILER_MS_PER_SAMPLE, opts.flamegraph, fgTitle) + if lde.verbose then + if ok then + ansi.printf("{cyan}Flamegraph written to %s", opts.flamegraph) + else + ansi.printf("{red}Flamegraph error: %s", err or "unknown error") end end end + end - if not runOk then - error(runErr, 0) - end + if opts.args then + arg = opts.args + arg[0] = scriptName + end - if opts.postexec then - return opts.postexec() - end + local ok, a, b, c, d, e, f = pcall(chunk, unpack(opts.args or {})) - return a, b, c, d, e, f - end) + finishProfiler() + + if ok and opts.postexec then + ok, a, b, c, d, e, f = pcall(opts.postexec) + end + + if stopProfiler then + stopProfiler() + end for k, v in pairs(oldEnvVars) do env.set(k, v) end if oldCwd then env.chdir(oldCwd) end @@ -365,7 +368,7 @@ local function executeWith(compile, opts, scriptName) package.loaders = oldLoaders package.path, package.cpath = oldPath, oldCPath - return ok, result + return ok, a, b, c, d, e, f end ---@param scriptPath string diff --git a/packages/lde/src/commands/eval.lua b/packages/lde/src/commands/eval.lua deleted file mode 100644 index 3f6b267..0000000 --- a/packages/lde/src/commands/eval.lua +++ /dev/null @@ -1,23 +0,0 @@ -local ansi = require("ansi") -local lde = require("lde-core") - ----@param code string -local function eval(code) - local pkg = lde.Package.open() - - local ok, result - if pkg then - pkg:installDependencies() - ok, result = pkg:runString(code) - else - ok, result = lde.runtime.executeString(code) - end - - if not ok then - ansi.printf("{red}%s", tostring(result)) - elseif result ~= nil then - print(tostring(result)) - end -end - -return eval diff --git a/packages/lde/src/commands/run.lua b/packages/lde/src/commands/run.lua index e37da92..27c399b 100644 --- a/packages/lde/src/commands/run.lua +++ b/packages/lde/src/commands/run.lua @@ -28,7 +28,7 @@ local function run(args) scriptArgs = args:drain() end - local function execute() + if not watch then if not pkg then if name and fs.exists(name) then local ok, err = lde.runtime.executeFile(name, { @@ -39,21 +39,23 @@ local function run(args) profile = profile, flamegraph = flamegraph }) + if not ok then error("Failed to run script: " .. (err or "Script exited with a non-zero exit code")) end + return end - ansi.printf("{red}%s\n", pkgErr) + ansi.printf("{red}%s", pkgErr) return end pkg:build() pkg:installDependencies() - local ok, err local scripts = pkg:readConfig().scripts + local ok, err if name and scripts and scripts[name] then ok, err = pkg:runScript(name) else @@ -61,22 +63,21 @@ local function run(args) end if not ok then - error("Failed to run script: " .. err) + ansi.printf("{red}Error: %s", err or "Script exited with a non-zero exit code") + os.exit(1) end - end - if not watch then - execute() return end local watchDir = pkg and pkg:getSrcDir() or env.cwd() local watcher = fs.watch(watchDir, function() end, { recursive = true }) if not watcher then - error("Failed to watch: " .. watchDir) + ansi.printf("{red}Failed to watch: %s", watchDir) + return end - ansi.printf("{cyan}Watching %s for changes...\n", watchDir) + ansi.printf("{cyan}Watching %s for changes...", watchDir) local spawnArgs = { "run" } if profile then spawnArgs[#spawnArgs + 1] = "--profile" end @@ -90,8 +91,9 @@ local function run(args) local function spawnChild() local child, err = process.spawn(env.execPath(), spawnArgs, { stdout = "inherit", stderr = "inherit" }) if not child then - ansi.printf("{red}Error: %s\n", tostring(err)) + ansi.printf("{red}Error: %s", tostring(err)) end + return child end @@ -99,7 +101,7 @@ local function run(args) while true do watcher.wait() - ansi.printf("{cyan}Change detected, restarting...\n") + ansi.printf("{cyan}Change detected, restarting...") if child then child:kill() end child = spawnChild() end diff --git a/packages/lde/src/commands/x.lua b/packages/lde/src/commands/x.lua index 56b4712..8973c03 100644 --- a/packages/lde/src/commands/x.lua +++ b/packages/lde/src/commands/x.lua @@ -28,7 +28,10 @@ local function x(args) end local pkg, err = resolvePackage(args) - if not pkg then error(err) end + if not pkg then + ansi.printf("{red}Error: %s", err) + os.exit(1) + end args:flag("") -- consume -- separator if present executePackage(pkg, args:drain() or {}, userCwd) diff --git a/packages/lde/src/init.lua b/packages/lde/src/init.lua index 39026da..847e5c6 100755 --- a/packages/lde/src/init.lua +++ b/packages/lde/src/init.lua @@ -165,7 +165,21 @@ end local evalCode = args:short("e") if evalCode then - require("lde.commands.eval")(evalCode) + local pkg = lde.Package.open() + local ok, result + if pkg then + pkg:installDependencies() + ok, result = pkg:runString(evalCode) + else + ok, result = lde.runtime.executeString(evalCode) + end + + if not ok then + ansi.printf("{red}%s", tostring(result)) + elseif result ~= nil then + print(tostring(result)) + end + return end @@ -193,79 +207,64 @@ if args:flag("ensure-mingw") then return end -local commands = {} -commands.help = require("lde.commands.help") -commands.init = require("lde.commands.initialize") -commands.new = require("lde.commands.new") -commands.upgrade = require("lde.commands.upgrade") -commands.add = require("lde.commands.add") -commands.remove = require("lde.commands.remove") -commands.run = require("lde.commands.run") -commands.x = require("lde.commands.x") -commands.install = require("lde.commands.install") -commands.i = commands.install -commands.sync = require("lde.commands.sync") -commands.bundle = require("lde.commands.bundle") -commands.compile = require("lde.commands.compile") -commands.test = require("lde.commands.test") -commands.tree = require("lde.commands.tree") -commands.update = require("lde.commands.update") -commands.outdated = require("lde.commands.outdated") -commands.uninstall = require("lde.commands.uninstall") -commands.publish = require("lde.commands.publish") -commands.repl = require("lde.commands.repl") +local commandFiles = { + help = "lde.commands.help", + init = "lde.commands.initialize", + new = "lde.commands.new", + upgrade = "lde.commands.upgrade", + add = "lde.commands.add", + remove = "lde.commands.remove", + run = "lde.commands.run", + x = "lde.commands.x", + install = "lde.commands.install", + i = "lde.commands.install", + sync = "lde.commands.sync", + bundle = "lde.commands.bundle", + compile = "lde.commands.compile", + test = "lde.commands.test", + tree = "lde.commands.tree", + update = "lde.commands.update", + outdated = "lde.commands.outdated", + uninstall = "lde.commands.uninstall", + publish = "lde.commands.publish", + repl = "lde.commands.repl", +} -- Commands that don't need the global cache dirs initialized local noInitCommands = { help = true } -local ok, err = xpcall(function() - local commandName = args:pop() - if not commandName then - commands.help(args) - return - end - - if not noInitCommands[commandName] and not treeOverride then - lde.global.init() - end +local commandName = args:pop() +if not commandName then + require("lde.commands.help")(args) + return +end - local commandHandler = commands[commandName] +if not noInitCommands[commandName] and not treeOverride then + lde.global.init() +end - if commandHandler then - commandHandler(args) - else - -- Fall back to package scripts, then to a loose file if it exists - local pkg = lde.Package.open() - local scripts = pkg and pkg:readConfig().scripts +local commandFile = commandFiles[commandName] +if commandFile then + require(commandFile)(args) +elseif fs.exists(commandName) then + -- TODO: Replace this hacky behavior + table.insert(args.raw, 1, commandName) + require("lde.commands.run")(args) +else + local pkg = lde.Package.open() + local scripts = pkg and pkg:readConfig().scripts - if scripts and scripts[commandName] then - ---@cast pkg -nil + if scripts and scripts[commandName] then + ---@cast pkg -nil - pkg:build() - pkg:installDependencies() + pkg:build() + pkg:installDependencies() - local ok, err = pkg:runScript(commandName) - if not ok then - error("Script '" .. commandName .. "' failed: " .. err) - end - elseif fs.exists(commandName) then - -- TODO: Replace this hacky behavior - table.insert(args.raw, 1, commandName) - commands.run(args) - else - ansi.printf("{red}Unknown command: %s", tostring(commandName)) + local ok, err = pkg:runScript(commandName) + if not ok then + error("Script '" .. commandName .. "' failed: " .. err) end + else + ansi.printf("{red}Unknown command: %s", tostring(commandName)) end -end, function(err) - return { msg = err, trace = debug.traceback(err, 2) } -end) - -if not ok then ---@cast err { msg: string, trace: string } - ansi.printf("{red}Error: %s", tostring(err.msg)) - - if env.var("DEBUG") then - print(err.trace) - end - - os.exit(1) end