ll

package module
v0.0.0-...-6c2e20b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2021 License: MIT Imports: 13 Imported by: 3

README

= LadyLua
:toc:
:toc-placement!:

Single static executable, batteries-included, Lua 5.1 interpreter. A fat https://github.com/yuin/gopher-lua[GopherLua] amalgamation of modules in Go and Lua.

toc::[]

== Changelog

Next release: *0.11.0 Tarot Cruncher* +
+ `string.trim` fix +
+ New module `csv` +
+ Take STDIN as code +

Current release: *0.10.0 Black Future* +
+ Aliases: `list:push` `list:pop` +
+ Aliases: `queue:push` `queue:pop` `queue:iterator` +
+ `tuple` module fixes and enhancements +
+ Renamed `tuple:elements` to `tuple:iterator` +
+ Renamed `bimap` module to `map` +
+ Renamed `deque` module to `queue` +
+ New module: `state` +
+ New module: `graph` +
+ New module: `object` +
+ New module: `ssh_config` +
+ New module: `date` +
+ New functions: `refmt.toml_to_json` and `refmt.json_to_toml` +
+ Removed `rr` module +

Old releases: +
*0.9.0 Scared Shrapnel* +
+ Loading plain Lua source is now done through `package.loaders` +
+ Faster VM startup time; From 18ms to <1ms in a test machine +
+ Now a module to support ./cmd builds +
+ Easier standalone programs +
+ Added `crypto.random` +
+ Added `crypto.fast_random` +
+ Removed `kapow` module +
+ New module: `guard` +
+ New module: `deque` +
+ New module: `bimap` +
+ New module: `tuple` +
+ New module: `argparse` +
+ New global function for extending modules: `extend` +
+ Moved `exec.cmd` and `exec.run` to `exec` extensions module +
+ Moved `json.array` and `json.object` to `json` extensions module +
+ Moved `string` extensions to separate extensions module +
+ Added `table.clone` +
+ Added `table.read_only` +
+ Bug fix: `list` +
+ gopher-lua fixes for `pcall`, `select`, `#` operator, and `string.gsub` +
+ Add `bitcask.open` configuration argument for maximum value size +

*0.8.0 Freckled Serpent* +
+ New setting for exec.*; timeout in seconds +
+ New json functions, array and object iterators +
+ New function: os.sleep +
+ Removed password module +
+ Replaced kapow.not_allowed with kapow.unprocessable +
+ Removed html module +
+ Stripped 1MiB by removing password and html modules +
+ New module: list +

*0.7.0 Negligent Clamshell* +
+ New module: bitcask +
+ New function: logger.time() +
+ New DSL module: Lopper +
+ Removed inspect module +
+ New function: crypto.valid_hmac +
+ DSL modules no longer embedded +
+ New module: refmt +
+ New module: rr +
+ Rename module uid to ksuid +
+ New module: uuid +
+ New module: ulid +
+ New function string.split +
+ New function string.splitv +
+ New function string.trim_end +
+ New function string.trim_start +
+ New function string.contains +
+ table.find is now recursive +
+ New function os.outbound_ip +
+ New function password.strength +

*0.6.0 Gummy Mastiff* +
+ New module: telegram +
+ New module: pushover +
+ New module: slack +
+ New module: logger +
+ New module: fsnotify +
+ redis: converted to object:method style +
+ buildah: New NOTIFY settings +

*0.5.3 Epidural Dollop* +
+ buildah: Consolidate APK command +

*0.5.2 Yelling Petunia* +
+ buildah: Removed default cmd config in ENTRYPOINT() +
+ buildah: Removed default arguments from MKDIR(), COPY(), ADD() +

*0.5.1 Failed Siesta* +
+ Fix buildah PUSH() +

*0.5.0 Surplus Siesta* +
+ New DSL module "buildah" +
+ New module "lz4" +
+ Selene configuration +
+ Removed redundant string.line_to_list() +
+ Added string.to_map() +
+ Add fourth return value for exec.command +



++++
<p align="center">
<img src="ll.svg?raw=true"/>
</p>
++++

== Why?
Lua is a good language but no one wants to use it for general-purpose scripting. Complaints are 1-based indexing and missing libraries. The latter is a valid concern. The 5.2+ split also does not help. I was convinced that GopherLua would be a good base for a kitchen-sink interpreter. Writing wrappers for the vast selection of Go packages would be a breeze.

== Reference
Since GopherLua is an implementation of Lua 5.1, you can use the official Lua 5.1 reference manual: https://www.lua.org/manual/5.1/manual.html[Lua 5.1 Manual]. Other resources are also useful just make sure they do not target 5.2+ versions. Search for PDFs of Lua 5.1 cheatsheets. The Learn in in 15 minutes series also has an entry for http://tylerneylon.com/a/learn-lua/[Lua].

== Standalone programs

See this -> https://github.com/tongson/patch_tuesday[patch_tuesday] Github repository for an example of a LadyLua standalone program.

== Modules
Check the `docs` directory for more information about these modules.

=== Available modules

[options="header",width="88%"]
|===
|Module      |Global |Type |Source           |License
|argparse    |N      |Lua  |argparse         |MIT
|bimap       |N      |Lua  |cw-lua           |MIT
|bitcask     |N      |Go   |                 |MIT
|crypto      |N      |Go   |gluacrypto       |MIT
|csv         |N      |Lua  |ftcsv            |MIT
|date        |N      |Lua  |date             |MIT
|deque       |N      |Lua  |cw-lua           |MIT
|exec        |Y      |Go   |                 |MIT
|fmt         |N      |Lua  |                 |MIT
|fs          |Y      |Go   |gopher-lfs       |Unlicense
|fsnotify    |N      |Go   |                 |MIT
|graph       |N      |Lua  |tsort            |BSD2
|guard       |N      |Lua  |guard            |MIT
|http        |N      |Go   |gluahttp         |MIT
|json        |N      |Go   |gopher-json      |Unlicense
|ksuid       |N      |Go   |                 |MIT
|list        |N      |Lua  |linked_list.lua  |MIT
|logger      |N      |Go   |                 |MIT
|lz4         |N      |Go   |                 |BSD3
|mysql       |N      |Go   |gluasql          |MIT
|object      |N      |Lua  |object           |Unlicense
|pushover    |N      |Go   |                 |MIT
|redis       |N      |Go   |                 |MIT
|refmt       |N      |Go   |                 |MIT
|rr          |N      |Go   |                 |MIT
|slack       |N      |Go   |                 |MIT
|ssh_config  |N      |Go   |ssh_config       |MIT
|state       |N      |Lua  |ahsm             |MIT
|telegram    |N      |Go   |                 |MIT
|template    |N      |Lua  |etlua            |MIT
|test        |N      |Lua  |u-test           |MIT
|tuple       |N      |Lua  |tuple.lua        |MIT
|ulid        |N      |Go   |                 |APL2
|uuid        |N      |Go   |                 |MPL2
|===

:note-caption: :information_source:
[NOTE]
====
If it says *N* in the *Global* field, you need to `require()` it. +
Modules that are type `Go` should be loaded through `ll.PreloadGo`
====

=== Extensions
These extensions extends a global namespace or module.

Load by adding a call to `extend`. Example:
----
extend("json")
----

[options="header",width="88%"]
|===
|Extension
|table
|string
|exec
|json
|===

=== DSL modules
Lua modules are single file Lua source that are loaded from the current working directory.

[options="header",width="50%"]
|===
|Module
|buildah
|lopper
|===

== Documentation and Testing
Tests are in the `tests` directory. We are using `u-test`. Within the test code is the documentation in AsciiDoc. Generated docs are in the `docs` directory. Check the `scripts/docs` directory for the command line to generate the docs.

== Uses
Besides general purpose scripting, a more specific use for me right now is using Lua for writing web apps. You can write it dynamic style like PHP but instead you have Lua. Another idea is hooking Go packages that interface with DevOps things. Instead of YAML you can program DevOps tools in Lua.

=== SAMPLE: shell script converted to Lua
Check this https://github.com/tongson/LadyLua/commit/0a1949060627fbee309e5549f0d00d0299ace3de?branch=0a1949060627fbee309e5549f0d00d0299ace3de&diff=split[diff] to get a feel of the conversion from a shell script to Lua.

=== Declarative scripting
Using metatables you can hide the plumbing and present a declarative interface. The following snippet can be found under the `scripts` directory. It is used to run the MariaDB container under systemd for testing the in-tree `mysql` module.

----
require('podman'){
  NAME = 'mariadb';
  URL  = 'docker://docker.io/library/mariadb';
  TAG  = '10.5';
  CPUS = '1';
  UNIT = require 'systemd.mariadb';
  DIR  = '/srv/podman/mariadb';
  always_update      = false;
  overwrite_password = false;
}
----

=== DSL modules
Instead of HCL or Dockerfile instructions you can possibly abstract subsystems with Lua. See the `buildah` module for an example of a DSL module.

== FAQ

=== Why not base off Lua 5.2+?

Sticking with 5.1 gets you a _finished_ language. For general purpose scripting, the 5.2+ feature are not really useful. You also have access to a significant collection of plain Lua modules. Excellent tools from the Roblox side like Selene and Stylua still works with 5.1.

== Statistics and numbers
|=======================
|Tests |188/188
|Static executable bytes |9007104
|=======================

=== Bloat tracker
Modules that adds significant bloat to the interpreter. If you don't need these maybe you can trim them from your fork. Just estimates though. The later added modules may have dependencies shared with earlier modules.

|======
|http |3-4MiB
|redis |800KiB
|mysql |500KiB
|slack |230KiB
|refmt |300KiB
|======

=== Benchmark
Wonder how it compares to PUC-Rio Lua 5.1.5 and LuaJIT2?

Here's a benchmark for object access time. Check the `bench/` directory for the code. The results are from the default 100M runs. GopherLua is fast enough for unconvoluted work. It also demonstrates that LuaJIT is too smart for these benchmarks.

.LadyLua
|=======================
|68.998712974 |Standard (solid)
|81.63775507999999 |Standard (metatable)
|73.37786640899998 |Object using closures (PiL 16.4)
|48.266743347000016 |Object using closures (noself)
|46.76494954999998 |Direct Access
|26.742789899 |Local Variable
|=======================

.Lua 5.1.5
|=======================
|12.906285 |Standard (solid)
|13.649843 |Standard (metatable)
|13.294447 |Object using closures (PiL 16.4)
|9.024326  |Object using closures (noself)
|5.618169  |Direct Access
|1.76135   |Local Variable
|=======================

.LuaJIT 2.1
|=======================
|0.200721  |Standard (solid)
|0.200649  |Standard (metatable)
|0.200672  |Object using closures (PiL 16.4)
|0.200635  |Object using closures (noself)
|0.200627  |Direct Access
|0.200628  |Local Variable
|=======================

Before you go disabling function inlining to reduce the executable size; here are the benchmarks for it.

.GopherLua (disabled function inlining)
|=======================
|97.82842299|Standard (solid)
|117.51864293899999|Standard (metatable)
|103.283447037|Object using closures (PiL 16.4)
|66.51865570900003|Object using closures (noself)
|69.64288394199997|Direct Access
|37.33177725300004|Local Variable
|=======================

Documentation

Overview

+build dsl

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DslLoader

func DslLoader(L *lua.LState, mod string)

func FillArg

func FillArg(L *lua.LState, args []string)

# # == *ll.FillArg*(*lua.LState, []string) # Capture command line arguments as the `arg` table in the global `_G` environment. # # === Arguments # [width="72%"] # |=== # |*lua.LState|The current `LState`; usually the result of `lua.NewState()` # |[]string |Usually `os.Args` # |===

func GlobalGo

func GlobalGo(L *lua.LState, name string)

# # == *ll.GlobalGo*(*lua.LState, string) # Load gopher-lua (Go) module into the global `_G` environment. + # # === Arguments # [width="72%"] # |=== # |*lua.LState|The current `LState`; usually the result of `lua.NewState()` # |string |Name of the module # |===

func GlobalLua

func GlobalLua(L *lua.LState, mod string)

# # == *ll.GlobalLua*(*lua.LState, string) # For adding Lua values into the global `_G` environment. # # === Arguments # [width="72%"] # |=== # |*lua.LState|The current `LState`; usually the result of `lua.NewState()` # |string |Basename of Lua source in `internal/lua` # |===

func Main

func Main(L *lua.LState, src string) error

# # == *ll.Main*(*lua.LState, string) # The entrypoint(main) Lua code for standalone projects. # # === Arguments # [width="72%"] # |=== # |*lua.LState|The current `LState`; usually the result of `lua.NewState()` # |string |Lua source code # |===

func Patch

func Patch(L *lua.LState, mod string)

# # == *ll.Patch*(*lua.LState, string) # For monkey-patching Lua values. # # [NOTE] # ==== # Severely degrades VM start up time. # ==== # # === Arguments # [width="72%"] # |=== # |*lua.LState|The current `LState`; usually the result of `lua.NewState()` # |string |Basename of Lua source in `internal/lua` # |===

func Preload

func Preload(L *lua.LState)

# = loader.go # :toc: # :toc-placement!: # # Module loaders. # # toc::[] # # == *ll.Preload*(*lua.LState) # Add `package.loaders` entry for loading plain Lua modules from `internal/lua`. + # This allows Lua code to `require()` these modules.

func PreloadGo

func PreloadGo(L *lua.LState, name string)

# # == *ll.PreloadGo*(*lua.LState, string) # Load gopher-lua (Go) module into `package.preload`. + # # === Arguments # [width="72%"] # |=== # |*lua.LState|The current `LState`; usually the result of `lua.NewState()` # |string |Name of the module # |===

func PreloadModule

func PreloadModule(L *lua.LState, name string, src string)

# # == *ll.PreloadModule*(*lua.LState, string, string) # Load plain Lua modules into `package.preload`. Useful for your own Lua modules loaded from standalone projects. # # === Arguments # [width="72%"] # |=== # |*lua.LState|The current `LState`; usually the result of `lua.NewState()` # |string |Name of the module # |string |Lua source code # |===

func ReadFile

func ReadFile(f embed.FS, p string) string

# # == *ll.ReadFile*(embed.FS, string) -> string # Read file from an `embed.FS` location. # # === Arguments # [width="72%"] # |=== # |embed.FS |Variable of embedded filesystem # |string |Filename # |=== # # === Returns # [width="72%"] # |=== # |string |Contents of file # |===

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL