API principal de Lua
ptool expone estos helpers principales del runtime directamente bajo ptool
y p.
ptool run <lua_file> ejecuta un script Lua e inyecta la variable global
ptool (o su alias p; por ejemplo, p.run es equivalente a ptool.run).
Para archivos que terminan en .lua, ptool <lua_file> es un atajo de CLI
con el mismo comportamiento.
El runtime Lua embebido conserva los globales básicos de Lua y, por defecto, solo expone estas bibliotecas estándar:
tablestringmathutf8
Los módulos integrados orientados al host, como io, os y package, no
están disponibles intencionadamente. Usa APIs de ptool como ptool.fs,
ptool.os, ptool.path y ptool.run para operaciones de sistema de
archivos, entorno, procesos, red y demás tareas de runtime.
Si quieres pasar argumentos a un script Lua, puedes hacerlo así:
ptool run script.lua --name alice -v a.txt b.txt
ptool script.lua --name alice -v a.txt b.txt
Luego los argumentos pueden analizarse con ptool.args.parse(...).
Aquí tienes un script de ejemplo:
ptool.use("v0.1.0")
ptool.run("echo", {"hello", "world"})
Se admite shebang, así que puedes añadir esto al comienzo del archivo:
#!/usr/bin/env ptool
ptool.use
v0.1.0- Introduced.
ptool.use declara la versión mínima de ptool requerida por un script.
ptool.use("v0.1.0")
- El argumento es una cadena de versión semántica (SemVer) y admite un prefijo
vopcional, comov0.1.0o0.1.0. - Si la versión requerida es superior a la versión actual de
ptool, el script sale de inmediato con un error indicando que la versión actual es demasiado antigua.
ptool.unindent
v0.1.0- Introduced.
ptool.unindent procesa cadenas multilínea eliminando el prefijo | después
de la indentación inicial en cada línea y recortando las líneas en blanco del
principio y del final.
local str = ptool.unindent([[
| line 1
| line 2
]])
Esto equivale a:
local str = [[line 1
line 2]]
ptool.inspect
v0.1.0- Introduced.
ptool.inspect(value[, options]) representa un valor Lua como una cadena
legible al estilo Lua. Su objetivo principal es depurar y mostrar el contenido
de tablas.
value(any, obligatorio): El valor Lua que se va a inspeccionar.options(table, opcional): Opciones de renderizado. Campos admitidos:indent(string, opcional): Indentación usada en cada nivel de anidación. Por defecto son dos espacios.multiline(boolean, opcional): Si las tablas se representan en varias líneas. Por defecto estrue.max_depth(integer, opcional): Profundidad máxima de anidación que se representará. Los valores más profundos se reemplazan por<max-depth>.
- Devuelve:
string.
Comportamiento:
- Las entradas tipo arreglo (
1..n) se representan primero. - Los demás campos de la tabla se representan después de la parte tipo arreglo, con un orden estable por clave.
- Las claves de cadena con forma de identificador se representan como
key = value; las demás se representan como[key] = value. - Las referencias recursivas a tablas se representan como
<cycle>. - Las funciones, threads y userdata se representan con valores marcadores como
<function>y<userdata>.
Ejemplo:
local value = {
"hello",
user = { name = "alice", tags = {"dev", "ops"} },
}
value.self = value
print(ptool.inspect(value))
print(ptool.inspect(value, { multiline = false }))
ptool.ask
v0.1.0- Introduced.v0.5.0- Added validation options and prompt subcommands.
ptool.ask ofrece prompts interactivos. Puedes llamarlo directamente para
pedir texto, o usar sus subprompts para confirmación, selección simple,
selección múltiple y entrada secreta.
Comportamiento común:
- Todos los prompts de
ptool.askrequieren un TTY interactivo. Ejecutarlos en un entorno no interactivo produce un error. - Si el usuario cancela un prompt, el script produce un error.
- Los nombres de opción desconocidos o los tipos de valor no válidos producen un error.
ptool.ask
ptool.ask(prompt[, options]) pide al usuario una línea de texto y devuelve la
respuesta.
prompt(string, obligatorio): El prompt que se muestra al usuario.options(table, opcional): Opciones del prompt. Campos admitidos:default(string, opcional): Valor por defecto usado cuando el usuario envía una respuesta vacía.help(string, opcional): Texto de ayuda adicional mostrado bajo el prompt.placeholder(string, opcional): Texto placeholder mostrado antes de que el usuario empiece a escribir.required(boolean, opcional): Si la respuesta debe ser no vacía.allow_empty(boolean, opcional): Si se acepta una respuesta vacía. El valor por defecto estrue.trim(boolean, opcional): Si se deben recortar los espacios al inicio y al final antes de devolver la respuesta.min_length(integer, opcional): Longitud mínima aceptada.max_length(integer, opcional): Longitud máxima aceptada.pattern(string, opcional): Expresión regular que la respuesta debe cumplir.
- Devuelve:
string.
Ejemplo:
local project = ptool.ask("Project name?", {
placeholder = "my-tool",
help = "Lowercase letters, digits, and dashes only",
required = true,
trim = true,
pattern = "^[a-z0-9-]+$",
})
ptool.ask.confirm
v0.5.0- Introduced.
ptool.ask.confirm(prompt[, options]) pide al usuario una respuesta de sí/no.
prompt(string, obligatorio): El prompt que se muestra al usuario.options(table, opcional): Opciones del prompt. Campos admitidos:default(boolean, opcional): Respuesta por defecto cuando el usuario pulsa Enter sin escribir.help(string, opcional): Texto de ayuda adicional mostrado bajo el prompt.
- Devuelve:
boolean.
Ejemplo:
local confirmed = ptool.ask.confirm("Continue?", {
default = true,
})
ptool.ask.select
v0.5.0- Introduced.
ptool.ask.select(prompt, items[, options]) pide al usuario elegir un elemento
de una lista.
prompt(string, obligatorio): El prompt que se muestra al usuario.items(table, obligatorio): Elementos candidatos. Cada entrada puede ser:- Un string, usado como etiqueta mostrada y como valor devuelto.
- Un table como
{ label = "Patch", value = "patch" }.
options(table, opcional): Opciones del prompt. Campos admitidos:help(string, opcional): Texto de ayuda adicional mostrado bajo el prompt.page_size(integer, opcional): Número máximo de filas mostradas a la vez.default_index(integer, opcional): Índice 1-based del elemento inicialmente seleccionado.
- Devuelve:
string.
Ejemplo:
local bump = ptool.ask.select("Select bump type", {
{ label = "Patch", value = "patch" },
{ label = "Minor", value = "minor" },
{ label = "Major", value = "major" },
}, {
default_index = 2,
})
ptool.ask.multiselect
v0.5.0- Introduced.
ptool.ask.multiselect(prompt, items[, options]) pide al usuario elegir cero o
más elementos de una lista.
prompt(string, obligatorio): El prompt que se muestra al usuario.items(table, obligatorio): Elementos candidatos. El formato es el mismo queptool.ask.select.options(table, opcional): Opciones del prompt. Campos admitidos:help(string, opcional): Texto de ayuda adicional mostrado bajo el prompt.page_size(integer, opcional): Número máximo de filas mostradas a la vez.default_indexes(table, opcional): Índices 1-based seleccionados por defecto.min_selected(integer, opcional): Cantidad mínima de elementos que deben seleccionarse.max_selected(integer, opcional): Cantidad máxima de elementos que pueden seleccionarse.
- Devuelve:
table.
Ejemplo:
local targets = ptool.ask.multiselect("Select targets", {
"linux",
"macos",
"windows",
}, {
default_indexes = { 1, 2 },
min_selected = 1,
})
ptool.ask.secret
v0.5.0- Introduced.
ptool.ask.secret(prompt[, options]) pide al usuario una entrada secreta, como
un token o una contraseña.
prompt(string, obligatorio): El prompt que se muestra al usuario.options(table, opcional): Opciones del prompt. Campos admitidos:help(string, opcional): Texto de ayuda adicional mostrado bajo el prompt.required(boolean, opcional): Si la respuesta debe ser no vacía.allow_empty(boolean, opcional): Si se acepta una respuesta vacía. El valor por defecto esfalse.confirm(boolean, opcional): Si se debe pedir al usuario que escriba el secreto dos veces. El valor por defecto esfalse.confirm_prompt(string, opcional): Prompt personalizado para el paso de confirmación.mismatch_message(string, opcional): Mensaje de error personalizado cuando las dos respuestas no coinciden.display_toggle(boolean, opcional): Si se permite mostrar temporalmente el secreto escrito.min_length(integer, opcional): Longitud mínima aceptada.max_length(integer, opcional): Longitud máxima aceptada.pattern(string, opcional): Expresión regular que la respuesta debe cumplir.
- Devuelve:
string.
Ejemplo:
local token = ptool.ask.secret("API token?", {
confirm = true,
min_length = 20,
})
ptool.config
v0.1.0- Introduced.
ptool.config establece la configuración de runtime del script.
Campos admitidos actualmente:
run(table, opcional): Configuración por defecto deptool.run. Campos admitidos:echo(boolean, opcional): Interruptor echo por defecto. Por defecto estrue.check(boolean, opcional): Si los fallos deben producir error por defecto. Por defecto esfalse.confirm(boolean, opcional): Si por defecto debe requerirse confirmación antes de ejecutar. Por defecto esfalse.retry(boolean, opcional): Si debe preguntarse al usuario si quiere reintentar después de una ejecución fallida cuandocheck = true. Por defecto esfalse.
Ejemplo:
ptool.config({
run = {
echo = false,
check = true,
confirm = false,
retry = false,
},
})
ptool.cd
v0.1.0- Introduced.
ptool.cd(path) actualiza el directorio actual de runtime de ptool.
path(string, obligatorio): Ruta del directorio destino, absoluta o relativa.
Comportamiento:
- Las rutas relativas se resuelven desde el directorio de runtime actual de
ptool. - El destino debe existir y debe ser un directorio.
- Esto actualiza el estado interno de runtime de
ptooly afecta a las APIs que usan ese cwd de runtime (comoptool.run,ptool.path.abspathyptool.path.relpath).
Ejemplo:
ptool.cd("foobar")
local res = ptool.run({ cmd = "pwd", stdout = "capture" })
print(res.stdout)
ptool.script_path
v0.4.0- Introduced.
ptool.script_path() devuelve la ruta absoluta del script de entrada actual.
- Devuelve:
string|nil.
Comportamiento:
- Al ejecutar con
ptool run <file>, devuelve la ruta del script de entrada como una ruta absoluta y normalizada. - La ruta devuelta queda fijada cuando se inicia el runtime y no cambia después
de
ptool.cd(...). - En
ptool repl, devuelvenil.
Ejemplo:
local script_path = ptool.script_path()
local script_dir = ptool.path.dirname(script_path)
local project_root = ptool.path.dirname(script_dir)
ptool.try
v0.4.0- Introduced.
ptool.try(fn) ejecuta fn y convierte los errores lanzados en valores de
retorno.
fn(function, obligatorio): Callback que se va a ejecutar.- Devuelve:
ok, value, err.
Reglas del valor devuelto:
- En caso de éxito,
ok = true,err = nilyvaluecontiene el resultado del callback. - Si el callback no devuelve valores,
valueesnil. - Si el callback devuelve un solo valor,
valuees ese valor. - Si el callback devuelve varios valores,
valuees una tabla tipo arreglo. - En caso de fallo,
ok = false,value = nilyerres una tabla.
Campos de error estructurado:
kind(string): Categoría estable del error, comoio_error,command_failed,invalid_argument,http_errorolua_error.message(string): Mensaje de error legible para humanos.op(string, opcional): Nombre de la API u operación, comoptool.fs.read.detail(string, opcional): Detalle adicional del fallo.path(string, opcional): Ruta implicada en un fallo del sistema de archivos.input(string, opcional): Entrada original que no pudo analizarse o validarse.cmd(string, opcional): Nombre del comando en fallos de comandos.status(integer, opcional): Código de salida o código HTTP cuando esté disponible.stderr(string, opcional): stderr capturado en fallos de comandos.url(string, opcional): URL implicada en un fallo HTTP.cwd(string, opcional): Directorio de trabajo efectivo en fallos de comandos.target(string, opcional): Objetivo SSH en fallos de comandos relacionados con SSH.retryable(boolean): Si tiene sentido reintentar. El valor por defecto esfalse.
Comportamiento:
- Las APIs de
ptoollanzan errores estructurados.ptool.trylos convierte en la tablaerranterior para que quien llama pueda ramificar segúnerr.kindy otros campos. - Los errores Lua normales también se capturan. En ese caso,
err.kindeslua_errory solo se garantizamessage. ptool.tryes la forma recomendada de manejar errores de APIs comoptool.fs.read,ptool.http.request,ptool.run(..., { check = true })yres:assert_ok().
Ejemplo:
local ok, content, err = ptool.try(function()
return ptool.fs.read("missing.txt")
end)
if not ok and err.kind == "io_error" then
print(err.op, err.path)
end
local ok2, _, err2 = ptool.try(function()
local res = ptool.run({
cmd = "sh",
args = {"-c", "echo bad >&2; exit 7"},
stderr = "capture",
})
res:assert_ok()
end)
if not ok2 and err2.kind == "command_failed" then
print(err2.cmd, err2.status, err2.stderr)
end
ptool.run
v0.1.0- Introduced.
ptool.run ejecuta comandos externos desde Rust.
Se admiten las siguientes formas de llamada:
ptool.run("echo hello world")
ptool.run("echo", "hello world")
ptool.run("echo", {"hello", "world"})
ptool.run("echo hello world", { echo = true })
ptool.run("echo", {"hello", "world"}, { echo = true })
ptool.run({ cmd = "echo", args = {"hello", "world"} })
ptool.run({ cmd = "echo", args = {"hello"}, stdout = "capture" })
Reglas de argumentos:
ptool.run(cmdline):cmdlinese divide usando reglas estilo shell (shlex). El primer elemento se trata como comando y el resto como argumentos.ptool.run(cmd, argsline):cmdse usa directamente como comando yargslinese divide en una lista de argumentos con reglas estilo shell (shlex).ptool.run(cmd, args):cmdes una cadena yargses un arreglo de cadenas.ptool.run(cmdline, options):optionssobrescribe la configuración de esta invocación, comoecho.ptool.run(cmd, args, options):argspuede ser una cadena o un arreglo de cadenas, yoptionssobrescribe la configuración de esta invocación, comoecho.ptool.run(options):optionses una tabla.- Cuando el segundo argumento es una tabla: si es un arreglo (claves enteras
consecutivas
1..n), se trata comoargs; en caso contrario se trata comooptions.
Reglas de valor devuelto:
- Siempre se devuelve una tabla con los siguientes campos:
ok(boolean): Si el código de salida es0.code(integer|nil): El código de salida del proceso. Si el proceso fue terminado por una señal, esto esnil.cmd(string): Nombre del comando usado para la ejecución.cwd(string): Directorio de trabajo efectivo usado para la ejecución.stdout(string, opcional): Presente cuandostdout = "capture".stderr(string, opcional): Presente cuandostderr = "capture".assert_ok(self)(function): Produce un error estructurado cuandook = false. El tipo de error escommand_failedy puede incluircmd,status,stderrycwd.
- El valor por defecto de
checkproviene deptool.config({ run = { check = ... } }). Si no se configura, el valor por defecto esfalse. Cuandocheck = false, quien llama puede inspeccionarokpor su cuenta o llamar ares:assert_ok(). - Cuando
check = trueyretry = true,ptool.runpregunta si debe reintentarse el comando fallido antes de producir el error final. - Cuando
check = true,ptool.runproduce el mismo error estructuradocommand_failedqueres:assert_ok(). Usaptool.try(...)si quieres capturarlo e inspeccionarlo desde Lua.
Ejemplo:
ptool.config({ run = { echo = false } })
ptool.run("echo from ptool")
ptool.run("echo", "from ptool")
ptool.run("echo", {"from", "ptool"})
ptool.run("echo from ptool", { echo = true })
ptool.run("echo", {"from", "ptool"}, { echo = true })
ptool.run("pwd")
local res = ptool.run({
cmd = "sh",
args = {"-c", "echo bad >&2; exit 7"},
stderr = "capture",
})
print(res.ok, res.code)
res:assert_ok()
También se admite ptool.run(options), donde options es una tabla con los
siguientes campos:
cmd(string, obligatorio): El nombre del comando o la ruta del ejecutable.args(string[], opcional): La lista de argumentos.cwd(string, opcional): El directorio de trabajo del proceso hijo.env(table, opcional): Variables de entorno adicionales, donde claves y valores son nombres y valores de variable.echo(boolean, opcional): Si debe imprimirse información del comando para esta ejecución. Si se omite, se usa el valor deptool.config({ run = { echo = ... } }); si también falta, el valor por defecto estrue.check(boolean, opcional): Si debe producirse un error inmediatamente cuando el código de salida no es0. Si se omite, se usa el valor deptool.config({ run = { check = ... } }); si también falta, el valor por defecto esfalse.confirm(boolean, opcional): Si debe pedirse confirmación al usuario antes de ejecutar. Si se omite, se usa el valor deptool.config({ run = { confirm = ... } }); si también falta, el valor por defecto esfalse.retry(boolean, opcional): Si debe preguntarse al usuario si quiere reintentar después de un fallo cuandocheck = true. Si se omite, se usa el valor deptool.config({ run = { retry = ... } }); si también falta, el valor por defecto esfalse.stdout(string, opcional): Estrategia de manejo de stdout. Valores admitidos:"inherit": Heredar hacia el terminal actual (por defecto)."capture": Capturar enres.stdout."null": Descartar la salida.
stderr(string, opcional): Estrategia de manejo de stderr. Valores admitidos:"inherit": Heredar hacia el terminal actual (por defecto)."capture": Capturar enres.stderr."null": Descartar la salida.
- Cuando
confirm = true:- Si el usuario rechaza la ejecución, se produce un error de inmediato.
- Si el entorno actual no es interactivo (sin TTY), se produce un error de inmediato.
- Cuando
retry = trueycheck = true:- Si el comando falla,
ptool.runpregunta si debe reintentarse el mismo comando. - Si el entorno actual no es interactivo (sin TTY), se produce un error de inmediato en lugar de pedir reintento.
- Si el comando falla,
Ejemplo:
ptool.run({
cmd = "echo",
args = {"hello"},
env = { FOO = "bar" },
})
local res = ptool.run({
cmd = "sh",
args = {"-c", "printf 'out'; printf 'err' >&2; exit 7"},
stdout = "capture",
stderr = "capture",
check = false,
})
print(res.ok, res.code)
print(res.stdout)
print(res.stderr)
res:assert_ok()
ptool.run_capture
Unreleased- Introduced.
ptool.run_capture ejecuta comandos externos desde Rust con las mismas formas
de llamada, reglas de argumentos, reglas de valor devuelto y opciones que
ptool.run.
La única diferencia es el manejo por defecto de los streams:
stdoutpor defecto es"capture".stderrpor defecto es"capture".
Puedes seguir sobrescribiendo cualquiera de los dos campos explícitamente en
options.
Ejemplo:
local res = ptool.run_capture("echo hello world")
print(res.stdout)
local res2 = ptool.run_capture({
cmd = "sh",
args = {"-c", "printf 'out'; printf 'err' >&2"},
})
print(res2.stdout)
print(res2.stderr)
local res3 = ptool.run_capture("echo hello", {
stderr = "inherit",
})
print(res3.stdout)