├── goos ├── test │ ├── test.file │ └── test_api.lua ├── api_test.go ├── loader.go ├── README.md └── api.go ├── http ├── test │ ├── data │ │ ├── index.html │ │ ├── test.txt │ │ ├── test1.txt │ │ └── mkcert.sh │ ├── server.key │ ├── test_server_handle.lua │ ├── loop.lua │ ├── test_serve_static.lua │ ├── server.crt │ ├── test_server_accept.lua │ ├── test_mtls_client.lua │ └── test_server.lua ├── client │ ├── interface │ │ ├── interface.go │ │ └── pure_client.go │ ├── loader.go │ └── client_example_test.go ├── util │ ├── loader.go │ └── util_example_test.go └── server │ ├── static_files_server.go │ ├── loader.go │ └── request.go ├── ioutil ├── test │ ├── file.test │ ├── .gitignore │ └── test_api.lua ├── api_test.go ├── loader.go ├── README.md ├── example_test.go └── api.go ├── log ├── test │ ├── .gitignore │ └── test_api.lua ├── api_test.go ├── loader.go ├── logger_config.go └── example_test.go ├── tac ├── test │ ├── .gitignore │ ├── test.txt │ └── test_api.lua ├── api_test.go ├── README.md ├── loader.go ├── example_test.go └── api.go ├── aws └── cloudwatch │ ├── test │ ├── .gitignore │ ├── test_api.lua │ ├── test_cloudwatch_logs.lua │ └── test_cloudwatch_get_metric_data.lua │ ├── api_test.go │ ├── api.go │ ├── loader.go │ ├── cloudwatch.go │ └── README.md ├── crypto ├── test │ └── data │ │ ├── 1.data.bin │ │ ├── 1.key.bin │ │ ├── 1.init.bin │ │ └── 1.expected.bin ├── api_test.go ├── example_test.go └── loader.go ├── zabbix ├── test │ ├── .gitignore │ ├── test_api.lua │ └── test_api_restream.lua ├── api_test.go ├── loader.go ├── types.go ├── README.md └── example_test.go ├── storage ├── test │ └── .gitignore ├── drivers │ ├── interfaces │ │ └── interfaces.go │ ├── drivers.go │ └── memory │ │ └── storage_set_get.go ├── api_test.go ├── loader.go ├── README.md └── example_test.go ├── .gitignore ├── plugin ├── test │ └── .gitignore ├── api_test.go ├── loader.go └── README.md ├── cmd ├── glua-libs │ └── .gitignore ├── api_test.go ├── loader.go ├── test │ └── test_api.lua ├── example_test.go └── README.md ├── telegram ├── test │ └── panda.jpg ├── types_util.go ├── api_test.go └── loader.go ├── tests ├── data │ ├── zabbix3 │ │ ├── zabbix.sql │ │ ├── Dockerfile │ │ ├── docker-compose.yml │ │ ├── nginx.conf │ │ └── ssl │ │ │ ├── nginx.crt │ │ │ └── nginx.key │ └── chef │ │ └── docker-compose.yaml ├── assert.lua ├── require.lua ├── testdata │ └── test_api.lua ├── runner.sh ├── testutil_test.go └── suite.lua ├── chef ├── test │ ├── test_api.lua │ ├── client.pem │ └── test_api_restream.lua ├── api_test.go ├── loader.go └── body.go ├── runtime ├── test │ └── test_api.lua ├── api_test.go ├── README.md ├── api.go ├── example_linux_test.go ├── example_windows_test.go └── loader.go ├── cert_util ├── test │ └── test_api.lua ├── loader.go ├── README.md ├── example_test.go ├── api_test.go └── api.go ├── preload.go ├── preload_test.go ├── stats ├── api_test.go ├── README.md ├── loader.go └── test │ └── test_api.lua ├── time ├── api_test.go ├── loader.go ├── README.md ├── test │ └── test_api.lua └── example_test.go ├── regexp ├── api_test.go ├── loader.go ├── example_test.go ├── test │ └── test_api.lua └── README.md ├── strings ├── api_test.go ├── loader.go ├── reader.go ├── README.md └── builder.go ├── template ├── api_test.go ├── README.md ├── mustache.go ├── example_test.go ├── loader.go └── test │ └── test_api.lua ├── .goreleaser.yml ├── bit ├── api_test.go ├── README.md ├── loader.go └── api.go ├── base64 ├── api_test.go ├── loader.go └── README.md ├── hex ├── api_test.go ├── loader.go ├── README.md └── test │ └── test_api.lua ├── inspect ├── README.md ├── example_test.go └── loader.go ├── pb ├── api_test.go ├── test │ └── test_api.lua ├── README.md ├── loader.go └── example_test.go ├── yaml ├── api_test.go ├── loader.go ├── example_test.go ├── encoder.go └── decoder.go ├── argparse ├── api_test.go ├── README.md ├── loader.go └── test │ └── test_api.lua ├── filepath ├── api_test.go ├── README.md └── loader.go ├── shellescape ├── api_test.go ├── README.md ├── loader.go ├── api.go └── example_test.go ├── xmlpath ├── api_test.go ├── test │ └── test_api.lua ├── README.md ├── example_test.go └── loader.go ├── json ├── api_test.go ├── loader.go ├── api.go └── example_test.go ├── humanize ├── api_test.go ├── loader.go ├── test │ └── test_api.lua ├── README.md ├── api.go └── example_test.go ├── db ├── api_test.go ├── loader.go ├── api_postgres.go ├── api_mysql.go ├── example_test.go └── api_sqlite.go ├── pprof ├── api_test.go ├── test │ └── test_api.lua ├── README.md ├── loader.go ├── example_test.go └── api.go ├── .github └── workflows │ ├── goreleaser.yaml │ └── ci.yaml ├── examples └── slack-alertmanager-silence-bot │ ├── functions.lua │ └── README.md ├── prometheus └── client │ ├── apt_test.go │ ├── metric_cache.go │ ├── README.md │ ├── example_test.go │ ├── loader.go │ ├── metric_config.go │ └── utils.go ├── tcp ├── README.md ├── example_test.go ├── api_test.go └── test │ └── test_api.lua ├── preload.lua ├── go.mod ├── io └── README.md └── LICENSE /goos/test/test.file: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /http/test/data/index.html: -------------------------------------------------------------------------------- 1 | OK -------------------------------------------------------------------------------- /ioutil/test/file.test: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /log/test/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /tac/test/.gitignore: -------------------------------------------------------------------------------- 1 | /file.txt 2 | -------------------------------------------------------------------------------- /aws/cloudwatch/test/.gitignore: -------------------------------------------------------------------------------- 1 | *.log -------------------------------------------------------------------------------- /crypto/test/data/1.data.bin: -------------------------------------------------------------------------------- 1 | Hello world -------------------------------------------------------------------------------- /http/test/data/test.txt: -------------------------------------------------------------------------------- 1 | hello world! -------------------------------------------------------------------------------- /http/test/data/test1.txt: -------------------------------------------------------------------------------- 1 | hello world! -------------------------------------------------------------------------------- /ioutil/test/.gitignore: -------------------------------------------------------------------------------- 1 | /*.data 2 | -------------------------------------------------------------------------------- /tac/test/test.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | -------------------------------------------------------------------------------- /zabbix/test/.gitignore: -------------------------------------------------------------------------------- 1 | /test.png 2 | -------------------------------------------------------------------------------- /storage/test/.gitignore: -------------------------------------------------------------------------------- 1 | /*.json 2 | db 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | .idea 3 | .vscode 4 | -------------------------------------------------------------------------------- /plugin/test/.gitignore: -------------------------------------------------------------------------------- 1 | /file.txt 2 | /payload.txt -------------------------------------------------------------------------------- /cmd/glua-libs/.gitignore: -------------------------------------------------------------------------------- 1 | /glua-libs 2 | /glua-libs.exe 3 | -------------------------------------------------------------------------------- /telegram/test/panda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vadv/gopher-lua-libs/HEAD/telegram/test/panda.jpg -------------------------------------------------------------------------------- /crypto/test/data/1.key.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vadv/gopher-lua-libs/HEAD/crypto/test/data/1.key.bin -------------------------------------------------------------------------------- /crypto/test/data/1.init.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vadv/gopher-lua-libs/HEAD/crypto/test/data/1.init.bin -------------------------------------------------------------------------------- /crypto/test/data/1.expected.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vadv/gopher-lua-libs/HEAD/crypto/test/data/1.expected.bin -------------------------------------------------------------------------------- /tests/data/zabbix3/zabbix.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vadv/gopher-lua-libs/HEAD/tests/data/zabbix3/zabbix.sql -------------------------------------------------------------------------------- /tests/assert.lua: -------------------------------------------------------------------------------- 1 | local assertions = require 'assertions' 2 | local orig_assert = assert 3 | return assertions:new { 4 | call = orig_assert, 5 | } 6 | -------------------------------------------------------------------------------- /tests/require.lua: -------------------------------------------------------------------------------- 1 | local assertions = require 'assertions' 2 | local orig_require = require 3 | return assertions:new { 4 | fail_now = true, 5 | call = orig_require, 6 | } 7 | 8 | -------------------------------------------------------------------------------- /chef/test/test_api.lua: -------------------------------------------------------------------------------- 1 | if os.getenv("CI") then 2 | -- travis 3 | function TestCI(t) 4 | t:Skip("CI") 5 | end 6 | else 7 | dofile("./test/test_api_restream.lua") 8 | end 9 | -------------------------------------------------------------------------------- /runtime/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local runtime = require("runtime") 2 | 3 | function Test_runtime(t) 4 | t:Logf("goos=%s", runtime.goos()) 5 | t:Logf("goarch=%s", runtime.goarch()) 6 | end 7 | -------------------------------------------------------------------------------- /tests/data/chef/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | chef-server: 2 | image: cbuisson/chef-server 3 | container_name: chef-server 4 | ports: 5 | - "2443:2443" 6 | environment: 7 | - SSL_PORT=2443 8 | -------------------------------------------------------------------------------- /zabbix/test/test_api.lua: -------------------------------------------------------------------------------- 1 | if os.getenv("CI") then 2 | -- travis 3 | function TestCI(t) 4 | t:Skip("CI") 5 | end 6 | else 7 | dofile("./test/test_api_restream.lua") 8 | end 9 | -------------------------------------------------------------------------------- /cert_util/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local cert_util = require("cert_util") 2 | 3 | function Test_cert_util(t) 4 | local tx, err = cert_util.not_after("127.0.0.1:1443", "127.0.0.1:1443") 5 | assert(not err, err) 6 | assert(tx == 1576161031, "cert: " .. tx) 7 | end 8 | -------------------------------------------------------------------------------- /preload.go: -------------------------------------------------------------------------------- 1 | package libs 2 | 3 | import ( 4 | plugin "github.com/vadv/gopher-lua-libs/plugin" 5 | lua "github.com/yuin/gopher-lua" 6 | ) 7 | 8 | // Preload preload all gopher lua packages 9 | func Preload(L *lua.LState) { 10 | plugin.PreloadAll(L) 11 | } 12 | -------------------------------------------------------------------------------- /http/client/interface/interface.go: -------------------------------------------------------------------------------- 1 | package http_interface 2 | 3 | import ( 4 | "net/http" 5 | "net/url" 6 | ) 7 | 8 | type LuaHTTPClient interface { 9 | DoRequest(*http.Request) (*http.Response, error) 10 | PostFormRequest(string, url.Values) (*http.Response, error) 11 | } 12 | -------------------------------------------------------------------------------- /preload_test.go: -------------------------------------------------------------------------------- 1 | package libs 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestPreload(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./preload.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /tac/api_test.go: -------------------------------------------------------------------------------- 1 | package tac 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestApi(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /stats/api_test.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestApi(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /time/api_test.go: -------------------------------------------------------------------------------- 1 | package time 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestApi(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /ioutil/api_test.go: -------------------------------------------------------------------------------- 1 | package ioutil 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestApi(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /regexp/api_test.go: -------------------------------------------------------------------------------- 1 | package regexp 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestApi(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /runtime/api_test.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestApi(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /strings/api_test.go: -------------------------------------------------------------------------------- 1 | package strings 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestApi(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /template/api_test.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | ) 8 | 9 | func TestApi(t *testing.T) { 10 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 11 | } 12 | -------------------------------------------------------------------------------- /tests/data/zabbix3/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mysql:5 2 | LABEL maintainer="Maksim Syomochkin " 3 | ENV MYSQL_ROOT_PASSWORD=root_pwd \ 4 | MYSQL_DATABASE=zabbix \ 5 | MYSQL_USER=zabbix \ 6 | MYSQL_PASSWORD=zabbix 7 | COPY zabbix.sql /docker-entrypoint-initdb.d/zabbix.sql 8 | EXPOSE 3306 9 | -------------------------------------------------------------------------------- /aws/cloudwatch/test/test_api.lua: -------------------------------------------------------------------------------- 1 | if os.getenv("CI") then 2 | -- travis: Include a test function that just skips 3 | function TestCI(t) 4 | t:Skip("CI") 5 | end 6 | else 7 | --dofile("./test/test_cloudwatch_logs.lua") 8 | dofile("./test/test_cloudwatch_get_metric_data.lua") 9 | end 10 | -------------------------------------------------------------------------------- /http/test/data/mkcert.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Make a test cert and key 4 | 5 | readonly MY_DIR="$(dirname "${BASH_SOURCE[0]}")" 6 | 7 | openssl req -nodes -x509 -newkey rsa:4096 -keyout "${MY_DIR}/test.key.pem" -out "${MY_DIR}/test.cert.pem" -sha256 \ 8 | -days 365000 -addext 'subjectAltName = IP:127.0.0.1' 9 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | builds: 2 | - main: ./cmd/glua-libs 3 | id: "glua-libs" 4 | binary: glua-libs 5 | goos: 6 | - linux 7 | - darwin 8 | - windows 9 | env: 10 | - CGO_ENABLED=0 11 | changelog: 12 | sort: asc 13 | filters: 14 | exclude: 15 | - '^docs:' 16 | - '^test:' 17 | -------------------------------------------------------------------------------- /bit/api_test.go: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | "github.com/vadv/gopher-lua-libs/tests" 8 | ) 9 | 10 | func TestApi(t *testing.T) { 11 | preload := tests.SeveralPreloadFuncs(Preload) 12 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 13 | } 14 | -------------------------------------------------------------------------------- /runtime/README.md: -------------------------------------------------------------------------------- 1 | # runtime [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/runtime?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/runtime) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local runtime = require("runtime") 7 | if not(runtime.goos() == "linux") then error("not linux") end 8 | if not(runtime.goarch() == "amd64") then error("not amd64") end 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /bit/README.md: -------------------------------------------------------------------------------- 1 | # bit [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/bit?bit.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/bit) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local bit = require("bit") 7 | 8 | local result, _ = bit.band(1, 0) 9 | print(result) 10 | -- Output: 0 11 | 12 | local result, _ = bit.lshift(10, 5) 13 | print(result) 14 | -- Output: 320 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /base64/api_test.go: -------------------------------------------------------------------------------- 1 | package base64 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/strings" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "testing" 8 | ) 9 | 10 | func TestApi(t *testing.T) { 11 | preload := tests.SeveralPreloadFuncs(Preload, strings.Preload) 12 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 13 | } 14 | -------------------------------------------------------------------------------- /hex/api_test.go: -------------------------------------------------------------------------------- 1 | package hex 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | "github.com/vadv/gopher-lua-libs/strings" 8 | "github.com/vadv/gopher-lua-libs/tests" 9 | ) 10 | 11 | func TestApi(t *testing.T) { 12 | preload := tests.SeveralPreloadFuncs(Preload, strings.Preload) 13 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 14 | } 15 | -------------------------------------------------------------------------------- /telegram/types_util.go: -------------------------------------------------------------------------------- 1 | package telegram 2 | 3 | import "encoding/json" 4 | 5 | func updatesToBytes(updates []Update) []byte { 6 | result, err := json.Marshal(&updates) 7 | if err != nil { 8 | panic(err) 9 | } 10 | return result 11 | } 12 | 13 | func (m Message) toBytes() []byte { 14 | result, err := json.Marshal(m) 15 | if err != nil { 16 | panic(err) 17 | } 18 | return result 19 | } 20 | -------------------------------------------------------------------------------- /inspect/README.md: -------------------------------------------------------------------------------- 1 | # inspect [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/inspect?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/inspect) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local inspect = require("inspect") 7 | 8 | local table = {a={b=2}} 9 | local result = inspect(table, {newline="", indent=""}) 10 | if not(result == "{a = {b = 2}}") then error("inspect") end 11 | ``` 12 | -------------------------------------------------------------------------------- /http/test/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BgUrgQQAIg== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MIGkAgEBBDA+4GLMGj94fCLbTBKXT9uRg+nUaUoOGuqj6emqQtIcZfKgt22xWYhE 6 | lRcYY4dMqDygBwYFK4EEACKhZANiAAS7vbDKnAbqhNXpgyWkkp9VI92DliylA4pZ 7 | m1bSZk0RMZCcXElYB9oEzSvwERYcrAaxpu1c+lQs9I7KFAujD8xQelltDhwFZ3EE 8 | zJ3P/BVtUmiTpQpxSDRnqeACgCWiWUA= 9 | -----END EC PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /http/test/test_server_handle.lua: -------------------------------------------------------------------------------- 1 | local http = require("http") 2 | local plugin = require("plugin") 3 | local time = require("time") 4 | 5 | local plugin_body = [[ 6 | local http = require("http") 7 | local server, err = http.server("127.0.0.1:2113") 8 | if err then error(err) end 9 | server:do_handle_file("./test/loop.lua") 10 | ]] 11 | 12 | local p = plugin.do_string(plugin_body) 13 | p:run() 14 | time.sleep(5) 15 | -------------------------------------------------------------------------------- /pb/api_test.go: -------------------------------------------------------------------------------- 1 | package pb 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | 8 | time "github.com/vadv/gopher-lua-libs/time" 9 | ) 10 | 11 | func TestApi(t *testing.T) { 12 | preload := tests.SeveralPreloadFuncs( 13 | time.Preload, 14 | Preload, 15 | ) 16 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 17 | } 18 | -------------------------------------------------------------------------------- /yaml/api_test.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/strings" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "testing" 8 | ) 9 | 10 | func TestApi(t *testing.T) { 11 | preload := tests.SeveralPreloadFuncs( 12 | Preload, 13 | strings.Preload, 14 | ) 15 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 16 | } 17 | -------------------------------------------------------------------------------- /argparse/api_test.go: -------------------------------------------------------------------------------- 1 | package argparse 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/inspect" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "testing" 8 | ) 9 | 10 | func TestApi(t *testing.T) { 11 | preload := tests.SeveralPreloadFuncs( 12 | inspect.Preload, 13 | Preload, 14 | ) 15 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 16 | } 17 | -------------------------------------------------------------------------------- /filepath/api_test.go: -------------------------------------------------------------------------------- 1 | package filepath 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/inspect" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "testing" 8 | ) 9 | 10 | func TestApi(t *testing.T) { 11 | preload := tests.SeveralPreloadFuncs( 12 | Preload, 13 | inspect.Preload, 14 | ) 15 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 16 | } 17 | -------------------------------------------------------------------------------- /stats/README.md: -------------------------------------------------------------------------------- 1 | # stats [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/stats?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/stats) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local stats = require("stats") 7 | 8 | local result, _ = stats.median({0,0,10}) 9 | print(result) 10 | -- Output: 0 11 | 12 | local result, _ = stats.percentile({0,0,10}, 100) 13 | print(result) 14 | -- Output: 10 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /cmd/api_test.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | 8 | runtime "github.com/vadv/gopher-lua-libs/runtime" 9 | ) 10 | 11 | func TestApi(t *testing.T) { 12 | preload := tests.SeveralPreloadFuncs( 13 | runtime.Preload, 14 | Preload, 15 | ) 16 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 17 | } 18 | -------------------------------------------------------------------------------- /shellescape/api_test.go: -------------------------------------------------------------------------------- 1 | package shellescape 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/inspect" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "testing" 8 | ) 9 | 10 | func TestApi(t *testing.T) { 11 | preload := tests.SeveralPreloadFuncs( 12 | inspect.Preload, 13 | Preload, 14 | ) 15 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "test/test_api.lua")) 16 | } 17 | -------------------------------------------------------------------------------- /storage/drivers/interfaces/interfaces.go: -------------------------------------------------------------------------------- 1 | package interfaces 2 | 3 | import lua "github.com/yuin/gopher-lua" 4 | 5 | type Driver interface { 6 | New(path string) (Driver, error) 7 | Get(key string, state *lua.LState) (lua.LValue, bool, error) 8 | Set(key string, value lua.LValue, ttl int64) error 9 | Keys() ([]string, error) 10 | Sync() error 11 | Close() error 12 | Dump(state *lua.LState) (map[string]lua.LValue, error) 13 | } 14 | -------------------------------------------------------------------------------- /aws/cloudwatch/api_test.go: -------------------------------------------------------------------------------- 1 | package cloudwatch 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | 8 | "github.com/vadv/gopher-lua-libs/inspect" 9 | ) 10 | 11 | func TestApi(t *testing.T) { 12 | preload := tests.SeveralPreloadFuncs( 13 | inspect.Preload, 14 | Preload, 15 | ) 16 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 17 | } 18 | -------------------------------------------------------------------------------- /xmlpath/api_test.go: -------------------------------------------------------------------------------- 1 | package xmlpath 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | 8 | inspect "github.com/vadv/gopher-lua-libs/inspect" 9 | ) 10 | 11 | func TestApi(t *testing.T) { 12 | preload := tests.SeveralPreloadFuncs( 13 | inspect.Preload, 14 | Preload, 15 | ) 16 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 17 | } 18 | -------------------------------------------------------------------------------- /shellescape/README.md: -------------------------------------------------------------------------------- 1 | # shellescape [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/shellescape?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/shellescape) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local shellescape = require("shellescape") 7 | 8 | escaped = shellescape.quote("foo bar baz") 9 | -- 'foo bar baz' 10 | 11 | escaped_command = shellescape.quote_command({ "echo", "foo bar baz" }) 12 | -- echo 'foo bar baz' 13 | ``` 14 | -------------------------------------------------------------------------------- /aws/cloudwatch/test/test_cloudwatch_logs.lua: -------------------------------------------------------------------------------- 1 | function Test_cloudwatch_logs(t) 2 | local cloudwatch = require("cloudwatch") 3 | 4 | local clw_client, err = cloudwatch.new() 5 | assert(not err, err) 6 | 7 | local filter = { 8 | log_group_name = os.getenv("LOG_GROUP_NAME"), 9 | start_time = 1557948000, 10 | end_time = 1557948200, 11 | } 12 | local err = clw_client:download("./test/test.log", filter, 100) 13 | assert(not err, err) 14 | end 15 | -------------------------------------------------------------------------------- /runtime/api.go: -------------------------------------------------------------------------------- 1 | // Package runtime implements golang runtime functionality for lua. 2 | package runtime 3 | 4 | import ( 5 | "runtime" 6 | 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // GOOS lua runtime.goos() return string 11 | func GOOS(L *lua.LState) int { 12 | L.Push(lua.LString(runtime.GOOS)) 13 | return 1 14 | } 15 | 16 | // GOARCH lua runtime.goarch() return string 17 | func GOARCH(L *lua.LState) int { 18 | L.Push(lua.LString(runtime.GOARCH)) 19 | return 1 20 | } 21 | -------------------------------------------------------------------------------- /tac/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local tac = require("tac") 2 | 3 | function Test_tac(t) 4 | local scanner, err = tac.open("./test/test.txt") 5 | assert(not err, err) 6 | 7 | local count_line = 3 8 | while true do 9 | local line = scanner:line() 10 | if line == nil then 11 | break 12 | end 13 | assert(tostring(count_line) == line, "must be: " .. tostring(count_line)) 14 | count_line = count_line - 1 15 | end 16 | scanner:close() 17 | end -------------------------------------------------------------------------------- /json/api_test.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/strings" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "testing" 8 | 9 | inspect "github.com/vadv/gopher-lua-libs/inspect" 10 | ) 11 | 12 | func TestApi(t *testing.T) { 13 | preload := tests.SeveralPreloadFuncs( 14 | Preload, 15 | inspect.Preload, 16 | strings.Preload, 17 | ) 18 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 19 | } 20 | -------------------------------------------------------------------------------- /humanize/api_test.go: -------------------------------------------------------------------------------- 1 | package humanize 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | 8 | inspect "github.com/vadv/gopher-lua-libs/inspect" 9 | time "github.com/vadv/gopher-lua-libs/time" 10 | ) 11 | 12 | func TestApi(t *testing.T) { 13 | preload := tests.SeveralPreloadFuncs( 14 | inspect.Preload, 15 | time.Preload, 16 | Preload, 17 | ) 18 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 19 | } 20 | -------------------------------------------------------------------------------- /inspect/example_test.go: -------------------------------------------------------------------------------- 1 | package inspect 2 | 3 | import ( 4 | "log" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // inspect(obj) 10 | func Example_full() { 11 | state := lua.NewState() 12 | Preload(state) 13 | source := ` 14 | local inspect = require("inspect") 15 | local table = {a={b=2}} 16 | print(inspect(table, {newline="", indent=""})) 17 | ` 18 | if err := state.DoString(source); err != nil { 19 | log.Fatal(err.Error()) 20 | } 21 | // Output: 22 | //{a = {b = 2}} 23 | } 24 | -------------------------------------------------------------------------------- /argparse/README.md: -------------------------------------------------------------------------------- 1 | # inspect [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/inspect?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/inspect) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | -- script.lua 7 | local argparse = require "argparse" 8 | 9 | local parser = argparse("script", "An example.") 10 | parser:argument("input", "Input file.") 11 | parser:option("-o --output", "Output file.", "a.out") 12 | parser:option("-I --include", "Include locations."):count("*") 13 | 14 | local args = parser:parse() 15 | ``` 16 | -------------------------------------------------------------------------------- /http/client/interface/pure_client.go: -------------------------------------------------------------------------------- 1 | package http_interface 2 | 3 | import ( 4 | "net/http" 5 | "net/url" 6 | ) 7 | 8 | func NewPureClient() *pureClient { 9 | return &pureClient{Client: &http.Client{}} 10 | } 11 | 12 | type pureClient struct { 13 | *http.Client 14 | } 15 | 16 | func (c *pureClient) DoRequest(req *http.Request) (*http.Response, error) { 17 | return c.Do(req) 18 | } 19 | 20 | func (c *pureClient) PostFormRequest(url string, data url.Values) (*http.Response, error) { 21 | return c.PostForm(url, data) 22 | } 23 | -------------------------------------------------------------------------------- /storage/drivers/drivers.go: -------------------------------------------------------------------------------- 1 | // multiple storage engines 2 | package drivers 3 | 4 | import ( 5 | interfaces "github.com/vadv/gopher-lua-libs/storage/drivers/interfaces" 6 | memory "github.com/vadv/gopher-lua-libs/storage/drivers/memory" 7 | ) 8 | 9 | var ( 10 | knownDrivers = make(map[string]interfaces.Driver, 0) 11 | ) 12 | 13 | func init() { 14 | knownDrivers[`memory`] = &memory.Storage{} 15 | } 16 | 17 | func Get(name string) (interfaces.Driver, bool) { 18 | // read only struct 19 | d, ok := knownDrivers[name] 20 | return d, ok 21 | } 22 | -------------------------------------------------------------------------------- /chef/api_test.go: -------------------------------------------------------------------------------- 1 | package chef_test 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | 8 | chef "github.com/vadv/gopher-lua-libs/chef" 9 | http "github.com/vadv/gopher-lua-libs/http" 10 | inspect "github.com/vadv/gopher-lua-libs/inspect" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | preload := tests.SeveralPreloadFuncs( 15 | chef.Preload, 16 | http.Preload, 17 | inspect.Preload, 18 | ) 19 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 20 | } 21 | -------------------------------------------------------------------------------- /crypto/api_test.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | "github.com/vadv/gopher-lua-libs/filepath" 8 | "github.com/vadv/gopher-lua-libs/hex" 9 | "github.com/vadv/gopher-lua-libs/ioutil" 10 | "github.com/vadv/gopher-lua-libs/tests" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | preload := tests.SeveralPreloadFuncs( 15 | Preload, 16 | filepath.Preload, 17 | hex.Preload, 18 | ioutil.Preload, 19 | ) 20 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 21 | } 22 | -------------------------------------------------------------------------------- /db/api_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows && sqlite 2 | // +build !windows,sqlite 3 | 4 | package db 5 | 6 | import ( 7 | "github.com/stretchr/testify/assert" 8 | "github.com/vadv/gopher-lua-libs/tests" 9 | "testing" 10 | 11 | inspect "github.com/vadv/gopher-lua-libs/inspect" 12 | time "github.com/vadv/gopher-lua-libs/time" 13 | ) 14 | 15 | func TestApi(t *testing.T) { 16 | preload := tests.SeveralPreloadFuncs( 17 | time.Preload, 18 | inspect.Preload, 19 | Preload, 20 | ) 21 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 22 | } 23 | -------------------------------------------------------------------------------- /tests/data/zabbix3/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/adubkov/py-zabbix 2 | zabbix-db: 3 | build: . 4 | container_name: zabbix-db 5 | 6 | zabbix: 7 | image: maksim77/zabbix:3 8 | container_name: zabbix 9 | ports: 10 | - "380:80" 11 | - "3443:443" 12 | - "30051:10051" 13 | links: 14 | - zabbix-db:zabbix.db 15 | volumes: 16 | - "./nginx.conf:/etc/nginx/hosts.d/default.conf" 17 | - "./ssl:/usr/local/share/zabbix/ssl" 18 | environment: 19 | - ZS_DBHost=zabbix.db 20 | - ZS_DBUser=zabbix 21 | - ZS_DBPassword=zabbix 22 | -------------------------------------------------------------------------------- /plugin/api_test.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/inspect" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "testing" 8 | 9 | ioutil "github.com/vadv/gopher-lua-libs/ioutil" 10 | time "github.com/vadv/gopher-lua-libs/time" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | preload := tests.SeveralPreloadFuncs( 15 | inspect.Preload, 16 | time.Preload, 17 | ioutil.Preload, 18 | Preload, 19 | ) 20 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 21 | } 22 | -------------------------------------------------------------------------------- /zabbix/api_test.go: -------------------------------------------------------------------------------- 1 | package zabbix_test 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | 8 | http "github.com/vadv/gopher-lua-libs/http" 9 | inspect "github.com/vadv/gopher-lua-libs/inspect" 10 | zabbix "github.com/vadv/gopher-lua-libs/zabbix" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | preload := tests.SeveralPreloadFuncs( 15 | zabbix.Preload, 16 | http.Preload, 17 | inspect.Preload, 18 | ) 19 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 20 | } 21 | -------------------------------------------------------------------------------- /pprof/api_test.go: -------------------------------------------------------------------------------- 1 | package pprof_test 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | lua_http "github.com/vadv/gopher-lua-libs/http" 6 | lua_pprof "github.com/vadv/gopher-lua-libs/pprof" 7 | "github.com/vadv/gopher-lua-libs/tests" 8 | lua_time "github.com/vadv/gopher-lua-libs/time" 9 | "testing" 10 | ) 11 | 12 | func TestApi(t *testing.T) { 13 | preload := tests.SeveralPreloadFuncs( 14 | lua_pprof.Preload, 15 | lua_http.Preload, 16 | lua_time.Preload, 17 | ) 18 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 19 | } 20 | -------------------------------------------------------------------------------- /telegram/api_test.go: -------------------------------------------------------------------------------- 1 | package telegram_test 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "testing" 7 | 8 | http "github.com/vadv/gopher-lua-libs/http" 9 | inspect "github.com/vadv/gopher-lua-libs/inspect" 10 | telegram "github.com/vadv/gopher-lua-libs/telegram" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | preload := tests.SeveralPreloadFuncs( 15 | telegram.Preload, 16 | http.Preload, 17 | inspect.Preload, 18 | ) 19 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 20 | } 21 | -------------------------------------------------------------------------------- /storage/api_test.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/tests" 6 | "os" 7 | "testing" 8 | 9 | inspect "github.com/vadv/gopher-lua-libs/inspect" 10 | time "github.com/vadv/gopher-lua-libs/time" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | preload := tests.SeveralPreloadFuncs( 15 | inspect.Preload, 16 | time.Preload, 17 | Preload, 18 | ) 19 | assert.NoError(t, os.MkdirAll("./test/db/badger/", 0755), "mkdir") 20 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 21 | } 22 | -------------------------------------------------------------------------------- /tests/testdata/test_api.lua: -------------------------------------------------------------------------------- 1 | local goos = require 'goos' 2 | 3 | function TestTempDir(t) 4 | -- Ensures that a tempdir created in subtests doesn't exist any longer after the test is run 5 | local tempDir = '' 6 | 7 | t:Run('createTmpDir', function(t) 8 | tempDir = t:TempDir() 9 | stat = goos.stat(tempDir) 10 | assert(stat, tempDir .. " does not exist") 11 | assert(stat.is_dir, tempDir .. " is not a dir") 12 | end) 13 | assert(tempDir ~= '', tempDir) 14 | assert(not goos.stat(tempDir), tempDir .. " exists after the subtest completes") 15 | end -------------------------------------------------------------------------------- /.github/workflows/goreleaser.yaml: -------------------------------------------------------------------------------- 1 | name: gorelease 2 | on: 3 | push: 4 | tags: 5 | - '*' 6 | jobs: 7 | 8 | test: 9 | runs-on: ubuntu-latest 10 | steps: 11 | 12 | - name: Checkout repo 13 | uses: actions/checkout@v2 14 | 15 | - name: Set up Go 16 | uses: actions/setup-go@v2 17 | with: 18 | go-version: 1.16 19 | 20 | - name: Run GoReleaser 21 | uses: goreleaser/goreleaser-action@v2 22 | with: 23 | version: latest 24 | args: release --rm-dist 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | -------------------------------------------------------------------------------- /cmd/loader.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds cmd to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local cmd = require("cmd") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("cmd", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "exec": Exec, 25 | } 26 | -------------------------------------------------------------------------------- /goos/api_test.go: -------------------------------------------------------------------------------- 1 | package goos 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | "github.com/vadv/gopher-lua-libs/tests" 9 | 10 | runtime "github.com/vadv/gopher-lua-libs/runtime" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | os.Setenv("ENV_VAR", "TEST=1") 15 | defer os.Unsetenv("ENV_VAR") 16 | 17 | os.Setenv("EMPTY_VAR", "") 18 | defer os.Unsetenv("EMPTY_VAR") 19 | 20 | preload := tests.SeveralPreloadFuncs( 21 | runtime.Preload, 22 | Preload, 23 | ) 24 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 25 | } 26 | -------------------------------------------------------------------------------- /examples/slack-alertmanager-silence-bot/functions.lua: -------------------------------------------------------------------------------- 1 | strings = require("strings") 2 | cmd = require("cmd") 3 | 4 | hex_to_char = function(x) 5 | return string.char(tonumber(x, 16)) 6 | end 7 | 8 | urldecode = function(url) 9 | if url == nil then 10 | return 11 | end 12 | url = url:gsub("+", " ") 13 | url = url:gsub("%%(%x%x)", hex_to_char) 14 | return url 15 | end 16 | 17 | format_time_with_offset = function(i) 18 | command = ("date --iso-8601=seconds --date '+"..i.." hour'") 19 | encoded, err = cmd.exec(command) 20 | if err then error(err) end 21 | return strings.trim((encoded.stdout), "\n") 22 | end 23 | -------------------------------------------------------------------------------- /tac/README.md: -------------------------------------------------------------------------------- 1 | # tac [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/tac?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/tac) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local file = io.open("data.txt", "w") 7 | file:write("1", "\n") 8 | file:write("2", "\n") 9 | file:write("3", "\n") 10 | 11 | local tac = require("tac") 12 | local scanner, err = tac.open("data.txt") 13 | if err then error(err) end 14 | 15 | while true do 16 | local line = scanner:line() 17 | if line == nil then break end 18 | print(line) 19 | end 20 | scanner:close() 21 | 22 | -- Output: 23 | -- 3 24 | -- 2 25 | -- 1 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | name: Build 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | go: [ '1.16', '1.17', '1.18', '1.19', '1.20','1.21' ] 16 | 17 | services: { } 18 | steps: 19 | - name: Set up Go 20 | uses: actions/setup-go@v2 21 | with: 22 | go-version: ${{ matrix.go }} 23 | 24 | - name: Checkout code 25 | uses: actions/checkout@v2 26 | 27 | - name: Run tests 28 | run: go test -v -tags 'sqlite' -race ./... 29 | -------------------------------------------------------------------------------- /runtime/example_linux_test.go: -------------------------------------------------------------------------------- 1 | // build +linux +amd64 2 | 3 | package runtime 4 | 5 | import ( 6 | "log" 7 | 8 | inspect "github.com/vadv/gopher-lua-libs/inspect" 9 | lua "github.com/yuin/gopher-lua" 10 | ) 11 | 12 | // runtime.goos(), runtime.goarch() 13 | func Example_package() { 14 | state := lua.NewState() 15 | Preload(state) 16 | inspect.Preload(state) 17 | source := ` 18 | local runtime = require("runtime") 19 | print(runtime.goos()) 20 | print(runtime.goarch()) 21 | ` 22 | if err := state.DoString(source); err != nil { 23 | log.Fatal(err.Error()) 24 | } 25 | // Output: 26 | // linux 27 | // amd64 28 | } 29 | -------------------------------------------------------------------------------- /tests/data/zabbix3/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default; 3 | listen 443 ssl; 4 | root /usr/local/src/zabbix/frontends/php; 5 | index index.php index.html; 6 | 7 | include /etc/nginx/conf.d/default-*.conf; 8 | include /data/conf/nginx/conf.d/default-*.conf; 9 | 10 | server_name 127.0.0.1; 11 | ssl_certificate /usr/local/share/zabbix/ssl/nginx.crt; 12 | ssl_certificate_key /usr/local/share/zabbix/ssl/nginx.key; 13 | 14 | # PHP backend is not in the default-*.conf file set, 15 | # as some vhost might not want to include it. 16 | include /etc/nginx/conf.d/php-location.conf; 17 | } 18 | -------------------------------------------------------------------------------- /cert_util/loader.go: -------------------------------------------------------------------------------- 1 | package cert_util 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds cert_util to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local cert_util = require("cert_util") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("cert_util", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "not_after": NotAfter, 25 | } 26 | -------------------------------------------------------------------------------- /cmd/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local cmd = require("cmd") 2 | local runtime = require("runtime") 3 | 4 | function TestNoTimeout(t) 5 | local command = runtime.goos() == "windows" and "timeout 1" or "sleep 1" 6 | local result, err = cmd.exec(command) 7 | assert(not err, err) 8 | t:Log(result.stdout) 9 | end 10 | 11 | function TestTimeout(t) 12 | local command = runtime.goos() == "windows" and "timeout 5" or "sleep 5" 13 | local result, err = cmd.exec(command, 1) 14 | assert(err, "timeout expected but did not occur") 15 | assert(err == "execute timeout", "expected 'execute timeout' but instead got '" .. err .. "'") 16 | end 17 | -------------------------------------------------------------------------------- /runtime/example_windows_test.go: -------------------------------------------------------------------------------- 1 | // build +windows +amd64 2 | 3 | package runtime 4 | 5 | import ( 6 | "log" 7 | 8 | inspect "github.com/vadv/gopher-lua-libs/inspect" 9 | lua "github.com/yuin/gopher-lua" 10 | ) 11 | 12 | // runtime.goos(), runtime.goarch() 13 | func Example_package() { 14 | state := lua.NewState() 15 | Preload(state) 16 | inspect.Preload(state) 17 | source := ` 18 | local runtime = require("runtime") 19 | print(runtime.goos()) 20 | print(runtime.goarch()) 21 | ` 22 | if err := state.DoString(source); err != nil { 23 | log.Fatal(err.Error()) 24 | } 25 | // Output: 26 | // windows 27 | // amd64 28 | } 29 | -------------------------------------------------------------------------------- /cert_util/README.md: -------------------------------------------------------------------------------- 1 | # cert_util [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/cert_util?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/cert_util) 2 | 3 | ## Functions 4 | 5 | - `not_after(hostname, ip:port)` - returns unix timestamp for hostname's ssl certificate expiration date. If a second argument will not be passed then will be used default (`hostname:443`). 6 | 7 | ## Examples 8 | 9 | ```lua 10 | local cert_util = require("cert_util") 11 | 12 | local tx, err = cert_util.not_after("google.com", "64.233.165.101:443") 13 | if err then error(err) end 14 | if not(tx == 1548838740) then error("error!") end 15 | ``` 16 | -------------------------------------------------------------------------------- /http/test/loop.lua: -------------------------------------------------------------------------------- 1 | local inspect = require("inspect") 2 | print(inspect(request)) 3 | print(inspect(response)) 4 | 5 | print("host:", request.host) 6 | print("method:", request.method) 7 | print("referer:", request.referer) 8 | print("proto:", request.proto) 9 | print("request_uri:", request.request_uri) 10 | print("remote_addr:", request.remote_addr) 11 | for k, v in pairs(request.headers) do 12 | print("header: ", k, v) 13 | end 14 | -- get body 15 | local body, err = request.body() 16 | if err then error(err) end 17 | print("body:", body) 18 | 19 | response:code(200) -- write header 20 | response:write(request.request_uri) 21 | response:done() 22 | -------------------------------------------------------------------------------- /runtime/loader.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds runtime to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local runtime = require("runtime") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("runtime", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "goos": GOOS, 25 | "goarch": GOARCH, 26 | } 27 | -------------------------------------------------------------------------------- /prometheus/client/apt_test.go: -------------------------------------------------------------------------------- 1 | package prometheus_client_test 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/http" 6 | prometheus "github.com/vadv/gopher-lua-libs/prometheus/client" 7 | "github.com/vadv/gopher-lua-libs/strings" 8 | "github.com/vadv/gopher-lua-libs/tests" 9 | "github.com/vadv/gopher-lua-libs/time" 10 | "testing" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | preload := tests.SeveralPreloadFuncs( 15 | prometheus.Preload, 16 | http.Preload, 17 | strings.Preload, 18 | time.Preload, 19 | ) 20 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 21 | } 22 | -------------------------------------------------------------------------------- /inspect/loader.go: -------------------------------------------------------------------------------- 1 | package inspect 2 | 3 | import ( 4 | _ "embed" 5 | lua "github.com/yuin/gopher-lua" 6 | ) 7 | 8 | //go:embed inspect.lua 9 | var lua_inspect string 10 | 11 | // Preload adds inspect to the given Lua state's package.preload table. After it 12 | // has been preloaded, it can be loaded using require: 13 | // 14 | // local inspect = require("inspect") 15 | func Preload(L *lua.LState) { 16 | L.PreloadModule("inspect", Loader) 17 | } 18 | 19 | // Loader is the module loader function. 20 | func Loader(L *lua.LState) int { 21 | if err := L.DoString(lua_inspect); err != nil { 22 | L.RaiseError("load library 'inspect' error: %s", err.Error()) 23 | } 24 | return 1 25 | } 26 | -------------------------------------------------------------------------------- /xmlpath/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local xml = require("xmlpath") 2 | local inspect = require("inspect") 3 | 4 | function Test_xmlpath(t) 5 | local data = [[ 6 | 7 | 8 | 9 | 10 | 11 | ]] 12 | local data_path = "//channel/@id" 13 | 14 | local node, err = xml.load(data) 15 | assert(not err, err) 16 | 17 | local path, err = xml.compile(data_path) 18 | assert(not err, err) 19 | 20 | local iter = path:iter(node) 21 | t:Log(inspect(iter)) 22 | 23 | for k, v in pairs(iter) do 24 | t:Logf("%s => %v", k, v:string()) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /argparse/loader.go: -------------------------------------------------------------------------------- 1 | package argparse 2 | 3 | import ( 4 | _ "embed" 5 | lua "github.com/yuin/gopher-lua" 6 | ) 7 | 8 | //go:embed argparse.lua 9 | var lua_argparse string 10 | 11 | // Preload adds inspect to the given Lua state's package.preload table. After it 12 | // has been preloaded, it can be loaded using require: 13 | // 14 | // local inspect = require("inspect") 15 | func Preload(L *lua.LState) { 16 | L.PreloadModule("argparse", Loader) 17 | } 18 | 19 | // Loader is the module loader function. 20 | func Loader(L *lua.LState) int { 21 | if err := L.DoString(lua_argparse); err != nil { 22 | L.RaiseError("load library 'argparse' error: %s", err.Error()) 23 | } 24 | return 1 25 | } 26 | -------------------------------------------------------------------------------- /pprof/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local pprof = require("pprof") 2 | local http = require("http") 3 | local time = require("time") 4 | 5 | function Test_pprof(t) 6 | local client = http.client() 7 | local pp = pprof.register(":1234") 8 | 9 | pp:enable() 10 | time.sleep(1) 11 | 12 | local req, err = http.request("GET", "http://127.0.0.1:1234/debug/pprof/goroutine") 13 | assert(not err, err) 14 | local resp, err = client:do_request(req) 15 | assert(not err, err) 16 | assert(resp.code == 200, "resp code: " .. resp.code) 17 | 18 | pp:disable() 19 | time.sleep(5) 20 | 21 | local resp, err = client:do_request(req) 22 | assert(err, "must be error") 23 | end 24 | -------------------------------------------------------------------------------- /cert_util/example_test.go: -------------------------------------------------------------------------------- 1 | package cert_util 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/vadv/gopher-lua-libs/time" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // cert_util.not_after("host", ) 11 | func Example_package() { 12 | state := lua.NewState() 13 | Preload(state) 14 | time.Preload(state) 15 | source := ` 16 | local cert_util = require("cert_util") 17 | local time = require("time") 18 | local tx, err = cert_util.not_after("google.com", "64.233.165.101:443") 19 | if err then error(err) end 20 | print(tx > time.unix()) 21 | ` 22 | if err := state.DoString(source); err != nil { 23 | log.Fatal(err.Error()) 24 | } 25 | // Output: 26 | // true 27 | } 28 | -------------------------------------------------------------------------------- /ioutil/loader.go: -------------------------------------------------------------------------------- 1 | package ioutil 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds ioutil to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local ioutil = require("ioutil") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("ioutil", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "read_file": ReadFile, 25 | "write_file": WriteFile, 26 | "copy": Copy, 27 | "copyn": CopyN, 28 | } 29 | -------------------------------------------------------------------------------- /shellescape/loader.go: -------------------------------------------------------------------------------- 1 | package shellescape 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds json to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local json = require("json") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("shellescape", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "quote": Quote, 25 | "quote_command": QuoteCommand, 26 | "strip_unsafe": StripUnsafe, 27 | } 28 | -------------------------------------------------------------------------------- /stats/loader.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds stats to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local stats = require("stats") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("stats", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "median": Median, 25 | "percentile": Percentile, 26 | "standard_deviation": StandardDeviation, 27 | } 28 | -------------------------------------------------------------------------------- /cmd/example_test.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "log" 5 | 6 | runtime "github.com/vadv/gopher-lua-libs/runtime" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // cmd.exec() 11 | func ExampleExec() { 12 | state := lua.NewState() 13 | Preload(state) 14 | runtime.Preload(state) 15 | source := ` 16 | local cmd = require("cmd") 17 | local runtime = require("runtime") 18 | 19 | local command = "sleep 1" 20 | if runtime.goos() == "windows" then command = "timeout 1" end 21 | 22 | local result, err = cmd.exec(command) 23 | if err then error(err) end 24 | print(result.status) 25 | ` 26 | if err := state.DoString(source); err != nil { 27 | log.Fatal(err.Error()) 28 | } 29 | // Output: 30 | // 0 31 | } 32 | -------------------------------------------------------------------------------- /time/loader.go: -------------------------------------------------------------------------------- 1 | package time 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds time to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local time = require("time") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("time", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "unix": Unix, 25 | "unix_nano": UnixNano, 26 | "sleep": Sleep, 27 | "parse": Parse, 28 | "format": Format, 29 | } 30 | -------------------------------------------------------------------------------- /humanize/loader.go: -------------------------------------------------------------------------------- 1 | package humanize 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds humanize to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local humanize = require("humanize") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("humanize", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "time": Time, 25 | "parse_bytes": ParseBytes, 26 | "ibytes": IBytes, 27 | "si": SI, 28 | } 29 | -------------------------------------------------------------------------------- /bit/loader.go: -------------------------------------------------------------------------------- 1 | package bit 2 | 3 | import lua "github.com/yuin/gopher-lua" 4 | 5 | // Preload adds bit to the given Lua state's package.preload table. After it 6 | // has been preloaded, it can be loaded using require: 7 | // 8 | // local bit = require("bit") 9 | func Preload(l *lua.LState) { 10 | l.PreloadModule("bit", Loader) 11 | } 12 | 13 | // Loader is the module loader function. 14 | func Loader(L *lua.LState) int { 15 | t := L.NewTable() 16 | L.SetFuncs(t, api) 17 | L.Push(t) 18 | return 1 19 | } 20 | 21 | var api = map[string]lua.LGFunction{ 22 | "band": Bitwise(and), 23 | "bor": Bitwise(or), 24 | "bxor": Bitwise(xor), 25 | "lshift": Bitwise(ls), 26 | "rshift": Bitwise(rs), 27 | "bnot": Not, 28 | } 29 | -------------------------------------------------------------------------------- /pb/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local pb = require('pb') 2 | local time = require('time') 3 | 4 | local count = 2 5 | 6 | local function run(bar) 7 | bar:start() 8 | 9 | for i = 1, count, 1 do 10 | time.sleep(1) 11 | bar:increment() 12 | end 13 | 14 | bar:finish() 15 | end 16 | 17 | function Test_predefined_template(t) 18 | local bar = pb.new(count) 19 | bar:configure({ template = 'simple' }) 20 | 21 | run(bar) 22 | end 23 | 24 | function Test_custom_template(t) 25 | local tmpl = string.format('%s {{ counters . }} {{bar . }} {{percent . }} {{ etime . }}', 'THIS IS PREFIX') 26 | 27 | local bar = pb.new(count) 28 | bar:configure({ template = tmpl }) 29 | run(bar) 30 | end 31 | -------------------------------------------------------------------------------- /tcp/README.md: -------------------------------------------------------------------------------- 1 | # tcp [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/tcp?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/tcp) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local tcp = require("tcp") 7 | 8 | -- http request 9 | local conn, err = tcp.open("google.com:80") 10 | err = conn:write("GET /\n\n") 11 | if err then error(err) end 12 | local result, err = conn:read(64*1024) 13 | print(result) 14 | 15 | -- ping pong game 16 | local conn, err = tcp.open(":12345") 17 | if err then error(err) end 18 | 19 | err = conn:write("ping") 20 | if err then error(err) end 21 | 22 | local result, err = conn:read() 23 | if err then error(err) end 24 | if (result == "pong") then error("must be pong message") end 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /goos/loader.go: -------------------------------------------------------------------------------- 1 | package goos 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds goos to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local goos = require("goos") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("goos", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "stat": Stat, 25 | "hostname": Hostname, 26 | "get_pagesize": Getpagesize, 27 | "mkdir_all": MkdirAll, 28 | "environ": Environ, 29 | } 30 | -------------------------------------------------------------------------------- /prometheus/client/metric_cache.go: -------------------------------------------------------------------------------- 1 | package prometheus_client 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | var metricCache = newPrometheusMetricCache() 8 | 9 | type promMetricCache struct { 10 | lock *sync.Mutex 11 | cache map[string]*luaMetric 12 | } 13 | 14 | func newPrometheusMetricCache() *promMetricCache { 15 | return &promMetricCache{ 16 | lock: &sync.Mutex{}, 17 | cache: make(map[string]*luaMetric, 0), 18 | } 19 | } 20 | 21 | func (c *promMetricCache) get(key string) (*luaMetric, bool) { 22 | c.lock.Lock() 23 | defer c.lock.Unlock() 24 | m, ok := c.cache[key] 25 | return m, ok 26 | } 27 | 28 | func (c *promMetricCache) set(key string, m *luaMetric) { 29 | c.lock.Lock() 30 | defer c.lock.Unlock() 31 | c.cache[key] = m 32 | } 33 | -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 | # template [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/template?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/template) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local template = require("template") 7 | 8 | local mustache, err = template.choose("mustache") 9 | 10 | local values = {name="world"} 11 | print( mustache:render("Hello {{name}}!", values) ) -- mustache:render_file() 12 | -- Output:"Hello world!" 13 | 14 | local values = {data = {"one", "two"}} 15 | print( mustache:render("{{#data}} {{.}} {{/data}}", values) ) 16 | -- Output:" one two " 17 | ``` 18 | 19 | ## Supported engines 20 | 21 | * [mustache](https://mustache.github.io/) [cbroglie/mustache](https://github.com/cbroglie/mustache) 22 | 23 | -------------------------------------------------------------------------------- /yaml/loader.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds yaml to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local yaml = require("yaml") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("yaml", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | registerYAMLEncoder(L) 18 | registerYAMLDecoder(L) 19 | 20 | t := L.NewTable() 21 | L.SetFuncs(t, api) 22 | L.Push(t) 23 | return 1 24 | } 25 | 26 | var api = map[string]lua.LGFunction{ 27 | "decode": Decode, 28 | "encode": Encode, 29 | "new_encoder": newYAMLEncoder, 30 | "new_decoder": newYAMLDecoder, 31 | } 32 | -------------------------------------------------------------------------------- /tests/runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ -z "$1" ] 4 | then 5 | echo "No argument supplied" 6 | echo "Possible args: up, down, kill, wait" 7 | exit 1 8 | fi 9 | 10 | type docker 11 | type docker-compose 12 | currdir="$(dirname $(realpath "$0"))" 13 | 14 | function docker_compose_action() 15 | { 16 | pushd "$currdir"/data/zabbix3 17 | docker-compose $1 $2 18 | popd 19 | pushd "$currdir"/data/chef 20 | docker-compose $1 $2 21 | popd 22 | } 23 | 24 | case $1 in 25 | up) 26 | docker_compose_action up -d 27 | ;; 28 | wait) 29 | while ! curl -k https://127.0.0.1:3443 --fail; do sleep 1; done 30 | docker exec -it chef-server chef-server-wait-lock 31 | ;; 32 | *) 33 | docker_compose_action $1 34 | ;; 35 | esac 36 | -------------------------------------------------------------------------------- /http/test/test_serve_static.lua: -------------------------------------------------------------------------------- 1 | local http = require("http") 2 | local plugin = require("plugin") 3 | local time = require("time") 4 | 5 | local plugin_body = [[ 6 | local http = require("http") 7 | local err = http.serve_static("./test/data", "127.0.0.1:2115") 8 | if err then error(err) end 9 | ]] 10 | 11 | local p = plugin.do_string(plugin_body) 12 | p:run() 13 | time.sleep(1) 14 | if not p:is_running() then 15 | error(p:error()) 16 | end 17 | 18 | local client = http.client() 19 | local req, err = http.request("GET", "http://127.0.0.1:2115") 20 | if err then error(err) end 21 | local resp, err = client:do_request(req) 22 | if err then error(err) end 23 | if not(resp.code == 200) then error("resp code") end 24 | if not(resp.body == "OK") then error("resp body, get:"..resp.body) end -------------------------------------------------------------------------------- /aws/cloudwatch/api.go: -------------------------------------------------------------------------------- 1 | // Package cloudwatch implements cloudwatch client api functionality for lua. 2 | package cloudwatch 3 | 4 | import ( 5 | lua "github.com/yuin/gopher-lua" 6 | ) 7 | 8 | // New lua new(profile, region) returns (clw_ud, err) 9 | func New(L *lua.LState) int { 10 | var awsProfile, awsRegion *string 11 | if L.GetTop() > 0 { 12 | val := L.CheckString(1) 13 | awsProfile = &val 14 | } 15 | if L.GetTop() > 1 { 16 | val := L.CheckString(2) 17 | awsProfile = &val 18 | } 19 | clw, err := newLauClW(awsProfile, awsRegion) 20 | if err != nil { 21 | L.Push(lua.LNil) 22 | L.Push(lua.LString(err.Error())) 23 | return 2 24 | } 25 | ud := L.NewUserData() 26 | ud.Value = clw 27 | L.SetMetatable(ud, L.GetTypeMetatable("clw_ud")) 28 | L.Push(ud) 29 | return 1 30 | } 31 | -------------------------------------------------------------------------------- /log/api_test.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/filepath" 6 | "github.com/vadv/gopher-lua-libs/strings" 7 | "github.com/vadv/gopher-lua-libs/tests" 8 | "testing" 9 | 10 | ioutil "github.com/vadv/gopher-lua-libs/ioutil" 11 | ) 12 | 13 | func TestApi(t *testing.T) { 14 | preload := tests.SeveralPreloadFuncs( 15 | ioutil.Preload, 16 | Preload, 17 | ) 18 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua")) 19 | } 20 | 21 | func TestLogLevelApi(t *testing.T) { 22 | preload := tests.SeveralPreloadFuncs( 23 | ioutil.Preload, 24 | filepath.Preload, 25 | strings.Preload, 26 | Preload, 27 | ) 28 | assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_loglevel.lua")) 29 | } 30 | -------------------------------------------------------------------------------- /humanize/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local humanize = require("humanize") 2 | local time = require("time") 3 | 4 | function Test_parse_bytes(t) 5 | local size, err = humanize.parse_bytes("1.3GiB") 6 | assert(not err, err) 7 | assert(size == 1395864371, "size: " .. tostring(size)) 8 | end 9 | 10 | function Test_ibytes(t) 11 | local size_string = humanize.ibytes(1395864371) 12 | assert(size_string == "1.3 GiB", "ibytes: " .. size_string) 13 | end 14 | 15 | function Test_time(t) 16 | local t = time.unix() - 2 17 | local time_string = humanize.time(t) 18 | assert(time_string == "2 seconds ago", "time: " .. time_string) 19 | end 20 | 21 | function Test_si(t) 22 | local si_result = humanize.si(1202121, "m") 23 | assert(si_result == "1.202121 Mm", "si: " .. tostring(si_result)) 24 | end 25 | -------------------------------------------------------------------------------- /pb/README.md: -------------------------------------------------------------------------------- 1 | # pb [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/strings?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/pb) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local pb = require('pb') 7 | local time = require('time') 8 | 9 | local count = 100 10 | local bar = pb.new(count) 11 | 12 | bar:start() 13 | 14 | for i=1, count, 1 do 15 | time.sleep(1) 16 | bar:increment() 17 | end 18 | 19 | bar:finish() 20 | ``` 21 | 22 | ### Configure progress bar 23 | - `bar:configure({})` - change progress bar parameters. Avaliable options: 24 | ``` 25 | template - use custom template (Please see https://github.com/cheggaaa/pb/blob/master/v3/element.go for all available elements) 26 | refresh_rate in ms (default 200ms) 27 | writer (default stderr). Only supported value is `stdout`. 28 | ``` 29 | -------------------------------------------------------------------------------- /template/mustache.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "sync" 5 | 6 | mustache "github.com/cbroglie/mustache" 7 | gluamapper "github.com/yuin/gluamapper" 8 | lua "github.com/yuin/gopher-lua" 9 | ) 10 | 11 | type luaMustache struct { 12 | sync.Mutex 13 | mapper *gluamapper.Mapper 14 | } 15 | 16 | func init() { 17 | nameFunc := func(name string) string { return name } 18 | RegisterTemplateEngine(`mustache`, &luaMustache{ 19 | mapper: gluamapper.NewMapper(gluamapper.Option{ 20 | NameFunc: nameFunc, 21 | }), 22 | }) 23 | } 24 | 25 | func (t *luaMustache) Render(data string, context *lua.LTable) (string, error) { 26 | var values map[string]interface{} 27 | if err := t.mapper.Map(context, &values); err != nil { 28 | return "", err 29 | } 30 | return mustache.Render(data, values) 31 | } 32 | -------------------------------------------------------------------------------- /hex/loader.go: -------------------------------------------------------------------------------- 1 | package hex 2 | 3 | import lua "github.com/yuin/gopher-lua" 4 | 5 | // Preload adds hex to the given Lua state's package.preload table. After it 6 | // has been preloaded, it can be loaded using require: 7 | // 8 | // local hex = require("hex") 9 | func Preload(L *lua.LState) { 10 | L.PreloadModule("hex", Loader) 11 | } 12 | 13 | // Loader is the module loader function. 14 | func Loader(L *lua.LState) int { 15 | registerHexDecoder(L) 16 | registerHexEncoder(L) 17 | 18 | // Register the encodings offered by hex go module. 19 | t := L.NewTable() 20 | L.SetFuncs(t, map[string]lua.LGFunction{ 21 | "decode_string": DecodeString, 22 | "encode_to_string": EncodeToString, 23 | "new_encoder": NewEncoder, 24 | "new_decoder": NewDecoder, 25 | }) 26 | L.Push(t) 27 | return 1 28 | } 29 | -------------------------------------------------------------------------------- /template/example_test.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "log" 5 | 6 | inspect "github.com/vadv/gopher-lua-libs/inspect" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | func Example_package() { 11 | state := lua.NewState() 12 | Preload(state) 13 | inspect.Preload(state) 14 | source := ` 15 | local template = require("template") 16 | 17 | local mustache, err = template.choose("mustache") 18 | 19 | local values = {name="world"} 20 | print( mustache:render("Hello {{name}}!", values) ) -- mustache:render_file(filename values) 21 | 22 | local values = {data = {"one", "two"}} 23 | print( mustache:render("{{#data}} {{.}} {{/data}}", values) ) 24 | ` 25 | if err := state.DoString(source); err != nil { 26 | log.Fatal(err.Error()) 27 | } 28 | // Output: 29 | // Hello world! 30 | // one two 31 | } 32 | -------------------------------------------------------------------------------- /pprof/README.md: -------------------------------------------------------------------------------- 1 | # pprof [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/pprof?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/pprof) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local pprof = require("pprof") 7 | local http = require("http") 8 | local time = require("time") 9 | 10 | local client = http.client() 11 | local pp = pprof.register(":1234") 12 | 13 | pp:enable() 14 | time.sleep(1) 15 | 16 | local req, err = http.request("GET", "http://127.0.0.1:1234/debug/pprof/goroutine") 17 | if err then error(err) end 18 | local resp, err = client:do_request(req) 19 | if err then error(err) end 20 | if not(resp.code == 200) then error("resp code") end 21 | 22 | pp:disable() 23 | time.sleep(5) 24 | 25 | local resp, err = client:do_request(req) 26 | if not(err) then error("must be error") end 27 | ``` 28 | -------------------------------------------------------------------------------- /tac/loader.go: -------------------------------------------------------------------------------- 1 | package tac 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds tac to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local tac = require("tac") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("tac", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | tac_ud := L.NewTypeMetatable(`tac_ud`) 19 | L.SetGlobal(`tac_ud`, tac_ud) 20 | L.SetField(tac_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "line": Line, 22 | "close": Close, 23 | })) 24 | 25 | t := L.NewTable() 26 | L.SetFuncs(t, api) 27 | L.Push(t) 28 | return 1 29 | } 30 | 31 | var api = map[string]lua.LGFunction{ 32 | "open": Open, 33 | } 34 | -------------------------------------------------------------------------------- /http/util/loader.go: -------------------------------------------------------------------------------- 1 | // Package http_util implements golang package http utility functionality for lua. 2 | 3 | package util 4 | 5 | import ( 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // Preload adds http to the given Lua state's package.preload table. After it 10 | // has been preloaded, it can be loaded using require: 11 | // 12 | // local http_util = require("http_util") 13 | func Preload(L *lua.LState) { 14 | L.PreloadModule("http_util", Loader) 15 | } 16 | 17 | // Loader is the module loader function. 18 | func Loader(L *lua.LState) int { 19 | t := L.NewTable() 20 | L.SetFuncs(t, api) 21 | L.Push(t) 22 | return 1 23 | } 24 | 25 | var api = map[string]lua.LGFunction{ 26 | "query_escape": QueryEscape, 27 | "query_unescape": QueryUnescape, 28 | "parse_url": ParseURL, 29 | "build_url": BuildURL, 30 | } 31 | -------------------------------------------------------------------------------- /http/test/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICEjCCAZegAwIBAgIJALZnSiZdfjoLMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT 3 | AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn 4 | aXRzIFB0eSBMdGQwHhcNMTgxMjAzMjEwNzE0WhcNMjgxMTMwMjEwNzE0WjBFMQsw 5 | CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu 6 | ZXQgV2lkZ2l0cyBQdHkgTHRkMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEu72wypwG 7 | 6oTV6YMlpJKfVSPdg5YspQOKWZtW0mZNETGQnFxJWAfaBM0r8BEWHKwGsabtXPpU 8 | LPSOyhQLow/MUHpZbQ4cBWdxBMydz/wVbVJok6UKcUg0Z6ngAoAlollAo1MwUTAd 9 | BgNVHQ4EFgQUV+m5+3aO+U4OVNdrD44VPC4j2BcwHwYDVR0jBBgwFoAUV+m5+3aO 10 | +U4OVNdrD44VPC4j2BcwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNpADBm 11 | AjEA7uTqy/aSohdeNRGmwJQFuDKuuj47RdHUABgFXjciB+rS2wAE6lXi8qXP4o+C 12 | 88iPAjEAnb7B5aZ5pktz30QzYoBcFoL/E8ueyrjz2vS3aQETEekG4tMU+JO92QVi 13 | JVnOjwz3 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /http/test/test_server_accept.lua: -------------------------------------------------------------------------------- 1 | local http = require("http_server") 2 | 3 | local server, err = http.server("127.0.0.1:1113") 4 | if err then error(err) end 5 | 6 | local running, count = true, 0 7 | while running do 8 | local request, response = server:accept() 9 | print("host:", request.host) 10 | print("method:", request.method) 11 | print("referer:", request.referer) 12 | print("proto:", request.proto) 13 | print("request_uri:", request.request_uri) 14 | print("remote_addr:", request.remote_addr) 15 | for k, v in pairs(request.headers) do 16 | print("header: ", k, v) 17 | end 18 | response:code(200) -- write header 19 | response:write(request.request_uri) 20 | response:done() 21 | count = count + 1 22 | running = (count < 10) 23 | end 24 | 25 | if count < 10 then 26 | error("count: "..tostring(count)) 27 | end 28 | -------------------------------------------------------------------------------- /json/loader.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds json to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local json = require("json") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("json", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | registerJSONEncoder(L) 18 | registerDecoder(L) 19 | registerJsonDecodedObject(L) 20 | 21 | t := L.NewTable() 22 | L.SetFuncs(t, api) 23 | L.Push(t) 24 | return 1 25 | } 26 | 27 | var api = map[string]lua.LGFunction{ 28 | "tableIsObject": TableIsObject, 29 | "decode": Decode, 30 | "encode": Encode, 31 | "new_encoder": newJSONEncoder, 32 | "new_decoder": newJSONDecoder, 33 | } 34 | -------------------------------------------------------------------------------- /pprof/loader.go: -------------------------------------------------------------------------------- 1 | package pprof 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds pprof to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local pprof = require("pprof") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("pprof", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | pprof_ud := L.NewTypeMetatable(`pprof_ud`) 19 | L.SetGlobal(`pprof_ud`, pprof_ud) 20 | L.SetField(pprof_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "enable": Enable, 22 | "disable": Disable, 23 | })) 24 | 25 | t := L.NewTable() 26 | L.SetFuncs(t, api) 27 | L.Push(t) 28 | return 1 29 | } 30 | 31 | var api = map[string]lua.LGFunction{ 32 | "register": Register, 33 | } 34 | -------------------------------------------------------------------------------- /xmlpath/README.md: -------------------------------------------------------------------------------- 1 | # xmlpath [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/xmlpath?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/xmlpath) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local xmlpath = require("xmlpath") 7 | 8 | local data = [[ 9 | 10 | 11 | 12 | 13 | 14 | ]] 15 | local data_path = "//channel/@id" 16 | 17 | -- xmlpath.load(data string) 18 | local node, err = xmlpath.load(data) 19 | if err then error(err) end 20 | 21 | -- xmlpath.compile(path string) 22 | local path, err = xmlpath.compile(data_path) 23 | if err then error(err) end 24 | 25 | -- path:iter(node) 26 | local iter = path:iter(node) 27 | 28 | for k, v in pairs(iter) do print(v:string()) end 29 | -- Output: 30 | -- 1 31 | -- 2 32 | -- x 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /crypto/example_test.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "log" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // crypto.md5(string) 10 | func ExampleMD5() { 11 | state := lua.NewState() 12 | Preload(state) 13 | source := ` 14 | local crypto = require("crypto") 15 | print(crypto.md5("1\n")) 16 | ` 17 | if err := state.DoString(source); err != nil { 18 | log.Fatal(err.Error()) 19 | } 20 | // Output: 21 | // b026324c6904b2a9cb4b88d6d61c81d1 22 | } 23 | 24 | // crypto.sha256(string) 25 | func ExampleSHA256() { 26 | state := lua.NewState() 27 | Preload(state) 28 | source := ` 29 | local crypto = require("crypto") 30 | print(crypto.sha256("1\n")) 31 | ` 32 | if err := state.DoString(source); err != nil { 33 | log.Fatal(err.Error()) 34 | } 35 | // Output: 36 | // 4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 37 | } 38 | -------------------------------------------------------------------------------- /shellescape/api.go: -------------------------------------------------------------------------------- 1 | package shellescape 2 | 3 | import ( 4 | "al.essio.dev/pkg/shellescape" 5 | lua "github.com/yuin/gopher-lua" 6 | ) 7 | 8 | func Quote(L *lua.LState) int { 9 | str := L.CheckString(1) 10 | escapedStr := shellescape.Quote(str) 11 | L.Push(lua.LString(escapedStr)) 12 | return 1 13 | } 14 | 15 | func QuoteCommand(L *lua.LState) int { 16 | args := L.CheckTable(1) 17 | argsLen := args.Len() 18 | goArgs := make([]string, argsLen) 19 | for i := 0; i < argsLen; i++ { 20 | goArgs[i] = lua.LVAsString(args.RawGetInt(i + 1)) 21 | } 22 | L.Pop(L.GetTop()) 23 | quotedCommand := shellescape.QuoteCommand(goArgs) 24 | L.Push(lua.LString(quotedCommand)) 25 | return 1 26 | } 27 | 28 | func StripUnsafe(L *lua.LState) int { 29 | str := L.CheckString(1) 30 | strippedStr := shellescape.StripUnsafe(str) 31 | L.Push(lua.LString(strippedStr)) 32 | return 1 33 | } 34 | -------------------------------------------------------------------------------- /chef/loader.go: -------------------------------------------------------------------------------- 1 | package chef 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds chef to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local chef = require("chef") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("chef", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | chef_client_ud := L.NewTypeMetatable(`chef_client_ud`) 19 | L.SetGlobal(`chef_client_ud`, chef_client_ud) 20 | L.SetField(chef_client_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "request": Request, 22 | "search": Search, 23 | })) 24 | t := L.NewTable() 25 | L.SetFuncs(t, api) 26 | L.Push(t) 27 | return 1 28 | } 29 | 30 | var api = map[string]lua.LGFunction{ 31 | "client": NewClient, 32 | } 33 | -------------------------------------------------------------------------------- /aws/cloudwatch/loader.go: -------------------------------------------------------------------------------- 1 | package cloudwatch 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds cloudwatch to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local cloudwatch = require("cloudwatch") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("cloudwatch", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | clwUd := L.NewTypeMetatable(`clw_ud`) 19 | L.SetGlobal(`clw_ud`, clwUd) 20 | L.SetField(clwUd, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "download": Download, 22 | "get_metric_data": GetMetricData, 23 | })) 24 | 25 | t := L.NewTable() 26 | L.SetFuncs(t, api) 27 | L.Push(t) 28 | return 1 29 | } 30 | 31 | var api = map[string]lua.LGFunction{ 32 | "new": New, 33 | } 34 | -------------------------------------------------------------------------------- /ioutil/README.md: -------------------------------------------------------------------------------- 1 | # ioutil [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/ioutil?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/ioutil) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local ioutil = require("ioutil") 7 | 8 | -- ioutil.write_file() 9 | local err = ioutil.write_file("./test/file.data", "content of test file") 10 | if err then error(err) end 11 | 12 | -- ioutil.read_file() 13 | local result, err = ioutil.read_file("./test/file.data") 14 | if err then error(err) end 15 | if not(result == "content of test file") then error("ioutil.read_file()") end 16 | 17 | -- ioutil.copy() 18 | local input_fh, err = io.open("./test/file.test", "r") 19 | assert(not err, err) 20 | local output_fh, err = io.open("./test/file2.data", "w") 21 | assert(not err, err) 22 | err = ioutil.copy(output_fh, input_fh) 23 | assert(not err, err) 24 | input_fh:close() 25 | output_fh:close() 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /crypto/loader.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import lua "github.com/yuin/gopher-lua" 4 | 5 | // Preload adds crypto to the given Lua state's package.preload table. After it 6 | // has been preloaded, it can be loaded using require: 7 | // 8 | // local crypto = require("crypto") 9 | func Preload(L *lua.LState) { 10 | L.PreloadModule("crypto", Loader) 11 | } 12 | 13 | // Loader is the module loader function. 14 | func Loader(L *lua.LState) int { 15 | t := L.NewTable() 16 | // Load the constants 17 | for name := range modeNames { 18 | t.RawSetString(name, lua.LString(name)) 19 | } 20 | L.SetFuncs(t, api) 21 | L.Push(t) 22 | return 1 23 | } 24 | 25 | var api = map[string]lua.LGFunction{ 26 | "md5": MD5, 27 | "sha256": SHA256, 28 | "aes_encrypt_hex": AESEncryptHex, 29 | "aes_decrypt_hex": AESDecryptHex, 30 | "aes_encrypt": AESEncrypt, 31 | "aes_decrypt": AESDecrypt, 32 | } 33 | -------------------------------------------------------------------------------- /pb/loader.go: -------------------------------------------------------------------------------- 1 | package pb 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds strings to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local pb = require("pb") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("pb", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | loggerUD := L.NewTypeMetatable(`pb_ud`) 19 | L.SetGlobal(`pb_ud`, loggerUD) 20 | L.SetField(loggerUD, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "configure": Configure, 22 | "start": Start, 23 | "increment": Increment, 24 | "finish": Finish, 25 | })) 26 | 27 | t := L.NewTable() 28 | L.SetFuncs(t, api) 29 | L.Push(t) 30 | return 1 31 | 32 | } 33 | 34 | var api = map[string]lua.LGFunction{ 35 | "new": New, 36 | } 37 | -------------------------------------------------------------------------------- /tac/example_test.go: -------------------------------------------------------------------------------- 1 | package tac 2 | 3 | import ( 4 | "log" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // tac.open(), tac_ud:line(), tac_ud:close() 10 | func Example() { 11 | state := lua.NewState() 12 | Preload(state) 13 | source := ` 14 | local file = io.open("./test/file.txt", "w") 15 | file:write("1", "\n") 16 | file:write("2", "\n") 17 | file:write("3", "\n") 18 | 19 | local tac = require("tac") 20 | local scanner, err = tac.open("./test/file.txt") 21 | if err then error(err) end 22 | 23 | while true do 24 | local line = scanner:line() 25 | if line == nil then break end 26 | print(line) 27 | end 28 | scanner:close() 29 | ` 30 | if err := state.DoString(source); err != nil { 31 | log.Fatal(err.Error()) 32 | } 33 | // Output: 34 | // 3 35 | // 2 36 | // 1 37 | } 38 | -------------------------------------------------------------------------------- /template/loader.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds template to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local template = require("template") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("template", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | template_ud := L.NewTypeMetatable(`template_ud`) 19 | L.SetGlobal(`template_ud`, template_ud) 20 | L.SetField(template_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "render": Render, 22 | "render_file": RenderFile, 23 | })) 24 | 25 | t := L.NewTable() 26 | L.SetFuncs(t, api) 27 | L.Push(t) 28 | return 1 29 | } 30 | 31 | var api = map[string]lua.LGFunction{ 32 | "choose": Choose, 33 | } 34 | -------------------------------------------------------------------------------- /cert_util/api_test.go: -------------------------------------------------------------------------------- 1 | package cert_util 2 | 3 | import ( 4 | "context" 5 | "github.com/stretchr/testify/assert" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "io" 8 | "net/http" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func runHttps(addr string, handler http.Handler) *http.Server { 14 | server := &http.Server{Addr: addr, Handler: handler} 15 | go func() { 16 | _ = server.ListenAndServeTLS("./test/cert.pem", "./test/key.pem") 17 | }() 18 | return server 19 | } 20 | 21 | func httpRouterGet(w http.ResponseWriter, r *http.Request) { 22 | _, _ = io.WriteString(w, "OK") 23 | } 24 | 25 | func TestApi(t *testing.T) { 26 | mux := http.NewServeMux() 27 | mux.HandleFunc("/get", httpRouterGet) 28 | server := runHttps(":1443", mux) 29 | t.Cleanup(func() { 30 | _ = server.Shutdown(context.Background()) 31 | }) 32 | time.Sleep(time.Second) 33 | 34 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 35 | } 36 | -------------------------------------------------------------------------------- /storage/loader.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds storage to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local storage = require("storage") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("storage", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | storage_ud := L.NewTypeMetatable(`storage_ud`) 19 | L.SetGlobal(`storage_ud`, storage_ud) 20 | L.SetField(storage_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "get": Get, 22 | "set": Set, 23 | "sync": Sync, 24 | "close": Close, 25 | "keys": Keys, 26 | "dump": Dump, 27 | })) 28 | 29 | t := L.NewTable() 30 | L.SetFuncs(t, api) 31 | L.Push(t) 32 | return 1 33 | } 34 | 35 | var api = map[string]lua.LGFunction{ 36 | "open": New, 37 | } 38 | -------------------------------------------------------------------------------- /time/README.md: -------------------------------------------------------------------------------- 1 | # time [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/time?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/time) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local time = require("time") 7 | 8 | -- time.unix(), time.sleep() 9 | local begin = time.unix() 10 | time.sleep(1.2) 11 | local stop = time.unix() 12 | local result = stop - begin 13 | result = math.floor(result * 10^2 + 0.5) / 10^2 14 | if not(result == 1) then error("time.sleep()") end 15 | 16 | -- time.parse(value, layout) 17 | local result, err = time.parse("Dec 2 03:33:05 2018", "Jan 2 15:04:05 2006") 18 | if err then error(err) end 19 | if not(result == 1543721585) then error("time.parse()") end 20 | 21 | -- time.format(value, layout, location) 22 | local result, err = time.format(1543721585, "Jan 2 15:04:05 2006", "Europe/Moscow") 23 | if err then error(err) end 24 | if not(result == "Dec 2 06:33:05 2018") then error("time.format()") end 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /http/server/static_files_server.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "net" 5 | "net/http" 6 | "time" 7 | 8 | lua "github.com/yuin/gopher-lua" 9 | ) 10 | 11 | // ServeStaticFiles lua http:serve_static("directory", ":port") return err 12 | func ServeStaticFiles(L *lua.LState) int { 13 | staticDir := L.CheckString(1) 14 | addr := L.CheckString(2) 15 | fs := http.FileServer(http.Dir(staticDir)) 16 | listener, err := net.Listen("tcp", addr) 17 | if err != nil { 18 | L.Push(lua.LString(err.Error())) 19 | return 1 20 | } 21 | server := &http.Server{Handler: fs, IdleTimeout: time.Second * 60} 22 | 23 | // shutdown 24 | go func(L *lua.LState, l net.Listener) { 25 | ctx := L.Context() 26 | if ctx != nil { 27 | select { 28 | case <-ctx.Done(): 29 | l.Close() 30 | } 31 | } 32 | }(L, listener) 33 | 34 | err = server.Serve(listener) 35 | if err != nil { 36 | L.Push(lua.LString(err.Error())) 37 | return 1 38 | } 39 | return 0 40 | } 41 | -------------------------------------------------------------------------------- /humanize/README.md: -------------------------------------------------------------------------------- 1 | # humanize [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/humanize?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/humanize) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local humanize = require("humanize") 7 | local time = require("time") 8 | 9 | -- humanize.parse_bytes 10 | local size, err = humanize.parse_bytes("1.3GiB") 11 | if err then error(err) end 12 | if not(size == 1395864371) then error("size: "..tostring(size)) end 13 | 14 | -- humanize.ibytes 15 | local size_string = humanize.ibytes(1395864371) 16 | if not(size_string == "1.3 GiB") then error("ibytes: "..size_string) end 17 | 18 | -- humanize.time 19 | local t = time.unix() - 2 20 | local time_string = humanize.time(t) 21 | if not(time_string == "2 seconds ago") then error("time: "..time_string) end 22 | 23 | -- humanize.si 24 | local si_result = humanize.si(0.212121, "m") 25 | if not(si_result == "212.121 mm") then error("si: "..tostring(si_result)) end 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /preload.lua: -------------------------------------------------------------------------------- 1 | function TestRequireModule(t) 2 | modules = { 3 | "argparse", 4 | "base64", 5 | "cert_util", 6 | "chef", 7 | "cloudwatch", 8 | "cmd", 9 | "crypto", 10 | "db", 11 | "filepath", 12 | "goos", 13 | "humanize", 14 | "inspect", 15 | "ioutil", 16 | "json", 17 | "log", 18 | "pb", 19 | "plugin", 20 | "pprof", 21 | "prometheus", 22 | "regexp", 23 | "runtime", 24 | "shellescape", 25 | "stats", 26 | "storage", 27 | "strings", 28 | "tac", 29 | "tcp", 30 | "telegram", 31 | "template", 32 | "time", 33 | "xmlpath", 34 | "yaml", 35 | "zabbix", 36 | } 37 | for _, module in ipairs(modules) do 38 | t:Run(module, function(t) 39 | require(module) 40 | end) 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /template/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local template = require("template") 2 | 3 | function Test_template(t) 4 | local mustache, err = template.choose("mustache") 5 | assert(not err, err) 6 | 7 | tests = { 8 | { 9 | name = "hello world", 10 | values = { name = "world" }, 11 | template = "Hello {{name}}!", 12 | expected = "Hello world!", 13 | }, 14 | { 15 | name = "one two", 16 | values = { data = { "one", "two" } }, 17 | template = "{{#data}} {{.}} {{/data}}", 18 | expected = " one two ", 19 | }, 20 | } 21 | for _, tt in ipairs(tests) do 22 | t:Run(tt.name, function(t) 23 | local result, err = mustache:render(tt.template, tt.values) 24 | assert(not err, err) 25 | assert(result == tt.expected, string.format([[expected "%s"; got "%s"]], tt.expected, result)) 26 | end) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /xmlpath/example_test.go: -------------------------------------------------------------------------------- 1 | package xmlpath 2 | 3 | import ( 4 | "log" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // xmlpath.compile, xmlpath.load, xmlpath_node_ud, xmlpath_path_ud, xmlpath_iter_ud 10 | func Example_full() { 11 | state := lua.NewState() 12 | Preload(state) 13 | source := ` 14 | local xmlpath = require("xmlpath") 15 | 16 | local data = [[ 17 | 18 | 19 | 20 | 21 | 22 | ]] 23 | local data_path = "//channel/@id" 24 | 25 | local node, err = xmlpath.load(data) 26 | if err then error(err) end 27 | 28 | local path, err = xmlpath.compile(data_path) 29 | if err then error(err) end 30 | 31 | local iter = path:iter(node) 32 | 33 | for k, v in pairs(iter) do print(v:string()) end 34 | ` 35 | if err := state.DoString(source); err != nil { 36 | log.Fatal(err.Error()) 37 | } 38 | // Output: 39 | // 1 40 | // 2 41 | // x 42 | } 43 | -------------------------------------------------------------------------------- /zabbix/loader.go: -------------------------------------------------------------------------------- 1 | package zabbix 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds zabbix to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local zabbix = require("zabbix") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("zabbix", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | zabbix_bot_ud := L.NewTypeMetatable(`zabbix_bot_ud`) 19 | L.SetGlobal(`zabbix_bot_ud`, zabbix_bot_ud) 20 | L.SetField(zabbix_bot_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "login": Login, 22 | "logout": Logout, 23 | "request": Request, 24 | "save_graph": SaveGraph, 25 | })) 26 | 27 | t := L.NewTable() 28 | L.SetFuncs(t, api) 29 | L.Push(t) 30 | return 1 31 | } 32 | 33 | var api = map[string]lua.LGFunction{ 34 | "bot": NewBot, 35 | "new": NewBot, 36 | } 37 | -------------------------------------------------------------------------------- /zabbix/types.go: -------------------------------------------------------------------------------- 1 | package zabbix 2 | 3 | import "encoding/json" 4 | 5 | type rpcRequest struct { 6 | Jsonrpc string `json:"jsonrpc"` 7 | Method string `json:"method"` 8 | Params interface{} `json:"params"` 9 | Auth string `json:"auth,omitempty"` 10 | Id int `json:"id"` 11 | } 12 | 13 | type rpcResponse struct { 14 | Jsonrpc string `json:"jsonrpc"` 15 | Error zbxError `json:"error"` 16 | Result interface{} `json:"result"` 17 | Id int `json:"id"` 18 | } 19 | 20 | type zbxError struct { 21 | Code int `json:"code"` 22 | Message string `json:"message"` 23 | Data string `json:"data"` 24 | } 25 | 26 | func (z *zbxError) Error() string { 27 | return z.Data 28 | } 29 | 30 | func (r *rpcResponse) resultToBytes() ([]byte, bool, error) { 31 | if result, ok := r.Result.(string); ok { 32 | return []byte(result), true, nil 33 | } 34 | result, err := json.Marshal(r.Result) 35 | return result, false, err 36 | } 37 | -------------------------------------------------------------------------------- /filepath/README.md: -------------------------------------------------------------------------------- 1 | # filepath [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/filepath?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/filepath) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local filepath = require("filepath") 7 | 8 | -- filepath.ext() 9 | local result = filepath.ext("/var/tmp/file.name") 10 | if not(result == ".name") then error("ext") end 11 | 12 | -- filepath.basename() 13 | local result = filepath.basename("/var/tmp/file.name") 14 | if not(result == "file.name") then error("basename") end 15 | 16 | -- filepath.dir() 17 | local result = filepath.dir("/var/tmp/file.name") 18 | if not(result == "/var/tmp") then error("dir") end 19 | 20 | -- filepath.join() 21 | local result = filepath.join("/var", "tmp", "file.name") 22 | if not(result == "/var/tmp/file.name") then error("join") end 23 | 24 | -- filepath.glob() 25 | local result = filepath.glob("/var/*/*.name") 26 | if not(result[1] == "/var/tmp/file.name") then error("glob") end 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /aws/cloudwatch/test/test_cloudwatch_get_metric_data.lua: -------------------------------------------------------------------------------- 1 | function Test_cloudwatch_get_metric_data(t) 2 | local cloudwatch = require("cloudwatch") 3 | local inspect = require("inspect") 4 | 5 | local clw_client, err = cloudwatch.new() 6 | assert(not err, err) 7 | 8 | local query1 = { 9 | namespace = "AWS/RDS", 10 | metric = "CPUUtilization", 11 | dimension_name = "DBInstanceIdentifier", 12 | dimension_value = os.getenv("DBINSTANCE"), 13 | stat = "Average", 14 | period = 60, 15 | } 16 | local query2 = { 17 | namespace = "AWS/RDS", 18 | metric = "ReadIOPS", 19 | dimension_name = "DBInstanceIdentifier", 20 | dimension_value = os.getenv("DBINSTANCE"), 21 | stat = "Average", 22 | period = 60, 23 | } 24 | local result, err = clw_client:get_metric_data({ queries = { cpu = query1, iops = query2 } }) 25 | assert(not err, err) 26 | t:Log(inspect(result)) 27 | end 28 | -------------------------------------------------------------------------------- /regexp/loader.go: -------------------------------------------------------------------------------- 1 | package regexp 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds regexp to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local regexp = require("regexp") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("regexp", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | regexp_ud := L.NewTypeMetatable(`regexp_ud`) 19 | L.SetGlobal(`regexp_ud`, regexp_ud) 20 | L.SetField(regexp_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "match": Match, 22 | "find_all_string_submatch": FindAllStringSubmatch, 23 | })) 24 | 25 | t := L.NewTable() 26 | L.SetFuncs(t, api) 27 | L.Push(t) 28 | return 1 29 | } 30 | 31 | var api = map[string]lua.LGFunction{ 32 | "compile": Compile, 33 | "match": SimpleMatch, 34 | "find_all_string_submatch": SimpleFindAllStringSubmatch, 35 | } 36 | -------------------------------------------------------------------------------- /storage/drivers/memory/storage_set_get.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "time" 5 | 6 | lua_json "github.com/vadv/gopher-lua-libs/json" 7 | 8 | lua "github.com/yuin/gopher-lua" 9 | ) 10 | 11 | func (s *Storage) Set(key string, value lua.LValue, ttl int64) error { 12 | data, err := lua_json.ValueEncode(value) 13 | if err != nil { 14 | return err 15 | } 16 | if !(ttl > 0) { 17 | ttl = 10000000000000 // max ttl 18 | } 19 | sValue := &storageValue{Value: data, MaxValidAt: time.Now().UnixNano() + (ttl * 1000000000)} 20 | s.Lock() 21 | s.Data[key] = sValue 22 | s.Unlock() 23 | return nil 24 | } 25 | 26 | func (s *Storage) Get(key string, L *lua.LState) (lua.LValue, bool, error) { 27 | s.Lock() 28 | defer s.Unlock() 29 | data, ok := s.Data[key] 30 | if !ok { 31 | return lua.LNil, false, nil 32 | } 33 | if !data.valid() { 34 | return lua.LNil, false, nil 35 | } 36 | value, err := lua_json.ValueDecode(L, data.Value) 37 | if err != nil { 38 | return lua.LNil, false, err 39 | } 40 | return value, true, nil 41 | } 42 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/vadv/gopher-lua-libs 2 | 3 | go 1.16 4 | 5 | require ( 6 | al.essio.dev/pkg/shellescape v1.5.1 7 | github.com/aws/aws-sdk-go v1.34.0 8 | github.com/cbroglie/mustache v1.0.1 9 | github.com/cheggaaa/pb/v3 v3.0.5 10 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e 11 | github.com/dustin/go-humanize v1.0.0 12 | github.com/go-sql-driver/mysql v1.5.0 13 | github.com/lib/pq v1.10.9 14 | github.com/mattn/go-sqlite3 v1.14.3 15 | github.com/mitchellh/mapstructure v1.3.2 // indirect 16 | github.com/montanaflynn/stats v0.6.3 17 | github.com/prometheus/client_golang v1.11.1 18 | github.com/stretchr/testify v1.5.1 19 | github.com/technoweenie/multipartstreamer v1.0.1 20 | github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7 21 | github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da 22 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a 23 | golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 // indirect 24 | gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc 25 | gopkg.in/yaml.v2 v2.3.0 26 | ) 27 | -------------------------------------------------------------------------------- /shellescape/example_test.go: -------------------------------------------------------------------------------- 1 | package shellescape 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | "log" 6 | ) 7 | 8 | func ExampleQuote() { 9 | L := lua.NewState() 10 | Preload(L) 11 | source := ` 12 | local shellescape = require("shellescape") 13 | print(shellescape.quote("foo")) 14 | ` 15 | if err := L.DoString(source); err != nil { 16 | log.Fatal(err) 17 | } 18 | // Output: 19 | // foo 20 | } 21 | 22 | func ExampleQuoteCommand() { 23 | L := lua.NewState() 24 | Preload(L) 25 | source := ` 26 | local shellescape = require("shellescape") 27 | print(shellescape.quote_command({"echo", "foo bar baz"})) 28 | ` 29 | if err := L.DoString(source); err != nil { 30 | log.Fatal(err) 31 | } 32 | // Output: 33 | // echo 'foo bar baz' 34 | } 35 | 36 | func ExampleStripUnsafe() { 37 | L := lua.NewState() 38 | Preload(L) 39 | source := ` 40 | local shellescape = require("shellescape") 41 | print(shellescape.strip_unsafe("foo\nbar")) 42 | ` 43 | if err := L.DoString(source); err != nil { 44 | log.Fatal(err) 45 | } 46 | // Output: 47 | // foobar 48 | } 49 | -------------------------------------------------------------------------------- /http/test/test_mtls_client.lua: -------------------------------------------------------------------------------- 1 | local http = require 'http_client' 2 | 3 | function TestMTLS(t) 4 | assert(tURL, 'tURL global is not set') 5 | 6 | t:Run('no-client-cert fails', function(t) 7 | local client = http.client{ 8 | insecure_ssl = true, 9 | } 10 | local req, err = http.request("GET", tURL) 11 | assert(not err, tostring(err)) 12 | local resp, err = client:do_request(req) 13 | assert(err, tostring(err)) 14 | end) 15 | 16 | t:Run('client-cert passes', function(t) 17 | local client = http.client { 18 | root_cas_pem_file = 'test/data/test.cert.pem', 19 | client_public_cert_pem_file = 'test/data/test.cert.pem', 20 | client_private_key_pem_file = 'test/data/test.key.pem', 21 | } 22 | local req, err = http.request("GET", tURL) 23 | assert(not err, tostring(err)) 24 | local resp, err = client:do_request(req) 25 | assert(not err, tostring(err)) 26 | assert(resp.code == 200, tostring(resp.code)) 27 | end) 28 | end 29 | -------------------------------------------------------------------------------- /goos/README.md: -------------------------------------------------------------------------------- 1 | # goos [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/goos?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/goos) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local goos = require("goos") 7 | 8 | -- stat 9 | local stat, err = goos.stat("./filename") 10 | if err then error(err) end 11 | print(stat.is_dir) 12 | print(stat.size) 13 | print(stat.mod_time) 14 | print(stat.mode) 15 | 16 | -- hostname 17 | local hostname, err = goos.hostname() 18 | if err then error(err) end 19 | print(hostname) 20 | 21 | -- get_pagesize 22 | local page_size = goos.get_pagesize() 23 | if not(page_size > 0) then error("bad pagesize") end 24 | 25 | -- mkdir_all 26 | goos.mkdir_all("./test/test_dir/test_dir/all") 27 | local stat, err = goos.stat("./test/test_dir/test_dir/all") 28 | if err then error(err) end 29 | 30 | -- environ 31 | local env = goos.environ() 32 | print(env.PATH) -- prints the PATH environment variable 33 | print(env.HOME) -- prints the HOME environment variable 34 | for key, value in pairs(env) do 35 | print(key .. "=" .. value) 36 | end 37 | ``` 38 | -------------------------------------------------------------------------------- /storage/README.md: -------------------------------------------------------------------------------- 1 | # storage [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/storage?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/storage) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local storage = require("storage") 7 | 8 | -- storage.open 9 | local s, err = storage.open("./test/db.json") 10 | if err then error(err) end 11 | 12 | -- storage:set(): key, value, ttl (default = 60s) 13 | local err = s:set("key", {"one", "two", 1}, 10) 14 | if err then error(err) end 15 | 16 | -- storage:get() 17 | local value, found, err = s:get("key") 18 | if err then error(err) end 19 | if not found then error("must be found") end 20 | -- value == {"one", "two", 1} 21 | 22 | -- storage:set(): override with set max ttl 23 | local err = s:set("key", "override", nil) 24 | local value, found, err = s:get("key") 25 | if not(value == "override") then error("must be found") end 26 | 27 | -- storage:keys() 28 | local list = s:keys() 29 | -- list == {"key"} 30 | 31 | -- storage:dump() 32 | local dump, err = s:dump() 33 | if err then error(err) end 34 | -- list == {"key" = "override"} 35 | 36 | ``` 37 | 38 | -------------------------------------------------------------------------------- /prometheus/client/README.md: -------------------------------------------------------------------------------- 1 | # prometheus [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/prometheus/client?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/prometheus/client) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local prometheus = require("prometheus") 7 | 8 | local pp = prometheus.register(":8080") 9 | pp:start() 10 | 11 | -- gauge / counter 12 | local gauge = prometheus.gauge({ -- prometheus.counter 13 | namespace="node_scout", 14 | subsystem="nf_conntrack", 15 | name="insert_failed", 16 | help="insert_failed from nf_conntrack", 17 | }) 18 | gauge:set(100) 19 | gauge:inc() 20 | gauge:add(1) 21 | 22 | -- gauge vector / counter vector 23 | local gauge = prometheus.gauge({ -- prometheus.counter 24 | namespace="node_scout", 25 | subsystem="nf_conntrack", 26 | name="insert_failed", 27 | help="insert_failed from nf_conntrack", 28 | labels = {"label_1", "label_2"} 29 | }) 30 | gauge:set(100, {"label_1":"one", "label_2":"two"}) 31 | gauge:inc({"label_1":"one", "label_2":"two"}) 32 | gauge:add(1, {"label_1":"one", "label_2":"two"}) 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /hex/README.md: -------------------------------------------------------------------------------- 1 | # hex [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/hex?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/hex) 2 | 3 | Lua module for [encoding/hex](https://pkg.go.dev/encoding/hex) 4 | 5 | ## Usage 6 | 7 | ### Encoding 8 | 9 | ```lua 10 | local hex = require("hex") 11 | 12 | s = hex.RawStdEncoding:encode_to_string("foo\01bar") 13 | print(s) 14 | Zm9vAWJhcg 15 | 16 | s = hex.StdEncoding:encode_to_string("foo\01bar") 17 | print(s) 18 | Zm9vAWJhcg== 19 | 20 | s = hex.RawURLEncoding:encode_to_string("this is a and should be encoded") 21 | print(s) 22 | dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA 23 | 24 | s = hex.URLEncoding:encode_to_string("this is a and should be encoded") 25 | print(s) 26 | dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA== 27 | 28 | ``` 29 | 30 | ### Decoding 31 | 32 | ```lua 33 | local hex = require 'hex' 34 | 35 | decoded, err = hex.decode_string("666f6f62617262617a") 36 | assert(not err, err) 37 | print(decoded) 38 | foobar 39 | 40 | encoded = hex.encode_to_string(decoded) 41 | print(encoded) 42 | 666f6f62617262617a 43 | ``` 44 | -------------------------------------------------------------------------------- /tests/testutil_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/vadv/gopher-lua-libs/goos" 6 | "github.com/vadv/gopher-lua-libs/inspect" 7 | "github.com/vadv/gopher-lua-libs/strings" 8 | "os" 9 | "testing" 10 | ) 11 | 12 | func TestSuite(t *testing.T) { 13 | preload := strings.Preload 14 | assert.NotZero(t, RunLuaTestFile(t, preload, "testdata/test_suite.lua")) 15 | } 16 | 17 | func TestApi(t *testing.T) { 18 | preload := goos.Preload 19 | assert.NotZero(t, RunLuaTestFile(t, preload, "testdata/test_api.lua")) 20 | } 21 | 22 | func TestAssertions(t *testing.T) { 23 | t.Run("passing", func(t *testing.T) { 24 | preload := inspect.Preload 25 | assert.NotZero(t, RunLuaTestFile(t, preload, "testdata/test_assertions_passing.lua")) 26 | }) 27 | t.Run("failing", func(t *testing.T) { 28 | if _, ok := os.LookupEnv("TEST_ASSERTIONS_FAILING"); !ok { 29 | t.Skip("Skipping unless TEST_ASSERTIONS_FAILING is set") 30 | } 31 | preload := inspect.Preload 32 | assert.NotZero(t, RunLuaTestFile(t, preload, "testdata/test_assertions_failing.lua")) 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /strings/loader.go: -------------------------------------------------------------------------------- 1 | package strings 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds strings to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local strings = require("strings") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("strings", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | readerMt := registerStringsReader(L) 18 | builderMt := registerStringsBuilder(L) 19 | 20 | t := L.NewTable() 21 | t.RawSetString("Reader", readerMt) 22 | t.RawSetString("Builder", builderMt) 23 | L.SetFuncs(t, api) 24 | L.Push(t) 25 | return 1 26 | } 27 | 28 | var api = map[string]lua.LGFunction{ 29 | "split": Split, 30 | "trim": Trim, 31 | "trim_space": TrimSpace, 32 | "trim_prefix": TrimPrefix, 33 | "trim_suffix": TrimSuffix, 34 | "has_prefix": HasPrefix, 35 | "has_suffix": HasSuffix, 36 | "contains": Contains, 37 | "new_reader": newStringsReader, 38 | "new_builder": newStringsBuilder, 39 | "fields": Fields, 40 | } 41 | -------------------------------------------------------------------------------- /strings/reader.go: -------------------------------------------------------------------------------- 1 | package strings 2 | 3 | import ( 4 | "github.com/vadv/gopher-lua-libs/io" 5 | lua "github.com/yuin/gopher-lua" 6 | "strings" 7 | ) 8 | 9 | const ( 10 | stringsReaderType = "strings.Reader" 11 | ) 12 | 13 | func CheckStringsReader(L *lua.LState, n int) *strings.Reader { 14 | ud := L.CheckUserData(n) 15 | if reader, ok := ud.Value.(*strings.Reader); ok { 16 | return reader 17 | } 18 | L.ArgError(n, stringsReaderType+" expected") 19 | return nil 20 | } 21 | 22 | func LVStringsReader(L *lua.LState, reader *strings.Reader) lua.LValue { 23 | ud := L.NewUserData() 24 | ud.Value = reader 25 | L.SetMetatable(ud, L.GetTypeMetatable(stringsReaderType)) 26 | return ud 27 | } 28 | 29 | func newStringsReader(L *lua.LState) int { 30 | s := L.CheckString(1) 31 | L.Pop(L.GetTop()) 32 | reader := strings.NewReader(s) 33 | L.Push(LVStringsReader(L, reader)) 34 | return 1 35 | } 36 | 37 | func registerStringsReader(L *lua.LState) lua.LValue { 38 | mt := L.NewTypeMetatable(stringsReaderType) 39 | readerTable := io.ReaderFuncTable(L) 40 | L.SetField(mt, "__index", readerTable) 41 | return mt 42 | } 43 | -------------------------------------------------------------------------------- /ioutil/example_test.go: -------------------------------------------------------------------------------- 1 | package ioutil 2 | 3 | import ( 4 | "log" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // ioutil.read_file(filepath) 10 | func ExampleReadFile() { 11 | state := lua.NewState() 12 | Preload(state) 13 | source := ` 14 | local file = io.open("./test/file.data", "w") 15 | file:write("content of test file", "\n") 16 | file:close() 17 | 18 | 19 | local ioutil = require("ioutil") 20 | local result, err = ioutil.read_file("./test/file.data") 21 | if err then error(err) end 22 | print(result) 23 | ` 24 | if err := state.DoString(source); err != nil { 25 | log.Fatal(err.Error()) 26 | } 27 | // Output: 28 | // content of test file 29 | } 30 | 31 | // ioutil.write_file(filepath) 32 | func ExampleWriteFile() { 33 | state := lua.NewState() 34 | Preload(state) 35 | source := ` 36 | local ioutil = require("ioutil") 37 | local err = ioutil.write_file("./test/file.data", "content of test file") 38 | if err then error(err) end 39 | ` 40 | if err := state.DoString(source); err != nil { 41 | log.Fatal(err.Error()) 42 | } 43 | // Output: 44 | // 45 | } 46 | -------------------------------------------------------------------------------- /pb/example_test.go: -------------------------------------------------------------------------------- 1 | package pb 2 | 3 | import ( 4 | "log" 5 | 6 | time "github.com/vadv/gopher-lua-libs/time" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | func ExampleAllParams() { 11 | state := lua.NewState() 12 | Preload(state) 13 | time.Preload(state) 14 | source := ` 15 | local pb = require('pb') 16 | local time = require('time') 17 | 18 | local count = 2 19 | local bar = pb.new(count) 20 | local template = string.format('%s {{ counters . }} {{percent . }} {{ etime . }}', '[custom template]') 21 | 22 | err = bar:configure({writer='stdout', refresh_rate=3001, template=template}) 23 | if err then error(err) end 24 | bar:start() 25 | 26 | for i=1, count, 1 do 27 | time.sleep(1) 28 | bar:increment() 29 | end 30 | bar:finish() 31 | ` 32 | if err := state.DoString(source); err != nil { 33 | log.Fatal(err.Error()) 34 | } 35 | // Output: 36 | // [custom template] 2 / 2 100.00% 2s 37 | 38 | } 39 | -------------------------------------------------------------------------------- /http/util/util_example_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "log" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // http_clien.parse_url(string) 10 | func ExampleParseUrl() { 11 | state := lua.NewState() 12 | Preload(state) 13 | source := ` 14 | local http_util = require("http_util") 15 | local url, err = http_util.parse_url("http://u1:p2@host:80/pathx?k1=v1&k2=v2&k1=vx") 16 | if err then error(err) end 17 | print(url.path) 18 | ` 19 | if err := state.DoString(source); err != nil { 20 | log.Fatal(err.Error()) 21 | } 22 | // Output: 23 | // /pathx 24 | } 25 | 26 | // http_clien.build_url(table) 27 | func ExampleBuidUrl() { 28 | state := lua.NewState() 29 | Preload(state) 30 | source := ` 31 | local http_util = require("http_util") 32 | local url, err = http_util.parse_url("http://u1:p2@host:80/pathx?k1=v1&k2=v2&k1=vx") 33 | if err then error(err) end 34 | url.path = "path2" 35 | print(http_util.build_url(url)) 36 | ` 37 | if err := state.DoString(source); err != nil { 38 | log.Fatal(err.Error()) 39 | } 40 | // Output: 41 | // http://u1:p2@host:80/path2?k1=v1&k1=vx&k2=v2 42 | } 43 | -------------------------------------------------------------------------------- /plugin/loader.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds plugin to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local plugin = require("plugin") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("plugin", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | pluginUd := L.NewTypeMetatable(`plugin_ud`) 19 | L.SetGlobal(`plugin_ud`, pluginUd) 20 | L.SetField(pluginUd, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "run": Run, 22 | "error": Error, 23 | "stop": Stop, 24 | "wait": Wait, 25 | "is_running": IsRunning, 26 | "done_channel": DoneChannel, 27 | })) 28 | 29 | t := L.NewTable() 30 | L.SetFuncs(t, api) 31 | L.Push(t) 32 | return 1 33 | } 34 | 35 | var api = map[string]lua.LGFunction{ 36 | "do_string": DoString, 37 | "do_file": DoFile, 38 | "do_string_with_payload": DoStringWithPayload, 39 | "do_file_with_payload": DoFileWithPayload, 40 | } 41 | -------------------------------------------------------------------------------- /db/loader.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds db to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local db = require("db") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("db", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | db_ud := L.NewTypeMetatable(`db_ud`) 19 | L.SetGlobal(`db_ud`, db_ud) 20 | L.SetField(db_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "query": Query, 22 | "exec": Exec, 23 | "stmt": Stmt, 24 | "command": Command, 25 | "close": Close, 26 | })) 27 | 28 | stmt_ud := L.NewTypeMetatable(`stmt_ud`) 29 | L.SetGlobal(`stmt_ud`, stmt_ud) 30 | L.SetField(stmt_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 31 | "query": StmtQuery, 32 | "exec": StmtExec, 33 | "close": StmtClose, 34 | })) 35 | 36 | t := L.NewTable() 37 | L.SetFuncs(t, api) 38 | L.Push(t) 39 | return 1 40 | } 41 | 42 | var api = map[string]lua.LGFunction{ 43 | "open": Open, 44 | } 45 | -------------------------------------------------------------------------------- /json/api.go: -------------------------------------------------------------------------------- 1 | // Package json implements json decode/encode functionality for lua. 2 | // original code: https://github.com/layeh/gopher-json 3 | package json 4 | 5 | import ( 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // Decode lua json.decode(string) returns (table, err) 10 | func Decode(L *lua.LState) int { 11 | str := L.CheckString(1) 12 | 13 | value, err := ValueDecode(L, []byte(str)) 14 | if err != nil { 15 | L.Push(lua.LNil) 16 | L.Push(lua.LString(err.Error())) 17 | return 2 18 | } 19 | L.Push(value) 20 | return 1 21 | } 22 | 23 | // Encode lua json.encode(obj) returns (string, err) 24 | func Encode(L *lua.LState) int { 25 | value := L.CheckAny(1) 26 | 27 | data, err := ValueEncode(value) 28 | if err != nil { 29 | L.Push(lua.LNil) 30 | L.Push(lua.LString(err.Error())) 31 | return 2 32 | } 33 | L.Push(lua.LString(string(data))) 34 | return 1 35 | } 36 | 37 | //TableIsObject lua json.tableIsObject marks a table as an object (to distinguish between [] and {}) 38 | func TableIsObject(L *lua.LState) int { 39 | table := L.CheckTable(1) 40 | L.SetMetatable(table, L.GetTypeMetatable(jsonTableIsObject)) 41 | return 0 42 | } 43 | -------------------------------------------------------------------------------- /yaml/example_test.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "log" 5 | 6 | inspect "github.com/vadv/gopher-lua-libs/inspect" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // yaml.decode(string) 11 | func Example() { 12 | state := lua.NewState() 13 | Preload(state) 14 | inspect.Preload(state) 15 | source := ` 16 | local yaml = require("yaml") 17 | local inspect = require("inspect") 18 | local text = [[ 19 | a: 20 | b: 1 21 | ]] 22 | local result, err = yaml.decode(text) 23 | if err then error(err) end 24 | print(inspect(result, {newline="", indent=""})) 25 | ` 26 | if err := state.DoString(source); err != nil { 27 | log.Fatal(err.Error()) 28 | } 29 | // Output: 30 | // {a = {b = 1}} 31 | } 32 | 33 | func ExampleEncode() { 34 | state := lua.NewState() 35 | Preload(state) 36 | inspect.Preload(state) 37 | source := ` 38 | local yaml = require("yaml") 39 | local encoded, err = yaml.encode({a = {b = 1}}) 40 | if err then error(err) end 41 | print(encoded) 42 | ` 43 | if err := state.DoString(source); err != nil { 44 | log.Fatal(err.Error()) 45 | } 46 | // Output: 47 | // a: 48 | // b: 1 49 | // 50 | } 51 | -------------------------------------------------------------------------------- /base64/loader.go: -------------------------------------------------------------------------------- 1 | package base64 2 | 3 | import ( 4 | "encoding/base64" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // Preload adds base64 to the given Lua state's package.preload table. After it 10 | // has been preloaded, it can be loaded using require: 11 | // 12 | // local base64 = require("base64") 13 | func Preload(L *lua.LState) { 14 | L.PreloadModule("base64", Loader) 15 | } 16 | 17 | // Loader is the module loader function. 18 | func Loader(L *lua.LState) int { 19 | registerBase64Encoding(L) 20 | registerBase64Encoder(L) 21 | registerBase64Decoder(L) 22 | 23 | // Register the encodings offered by base64 go module. 24 | t := L.NewTable() 25 | L.SetField(t, "RawStdEncoding", LVBase64Encoding(L, base64.RawStdEncoding)) 26 | L.SetField(t, "RawURLEncoding", LVBase64Encoding(L, base64.RawURLEncoding)) 27 | L.SetField(t, "StdEncoding", LVBase64Encoding(L, base64.StdEncoding)) 28 | L.SetField(t, "URLEncoding", LVBase64Encoding(L, base64.URLEncoding)) 29 | L.SetFuncs(t, map[string]lua.LGFunction{ 30 | "new_encoding": NewEncoding, 31 | "new_encoder": NewEncoder, 32 | "new_decoder": NewDecoder, 33 | }) 34 | L.Push(t) 35 | return 1 36 | } 37 | -------------------------------------------------------------------------------- /filepath/loader.go: -------------------------------------------------------------------------------- 1 | package filepath 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds filepath to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local filepath = require("filepath") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("filepath", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | t := L.NewTable() 18 | L.SetFuncs(t, api) 19 | L.Push(t) 20 | return 1 21 | } 22 | 23 | var api = map[string]lua.LGFunction{ 24 | "abs": Abs, 25 | "basename": Basename, 26 | "clean": Clean, 27 | "dir": Dir, 28 | "eval_symlinks": EvalSymlinks, 29 | "from_slash": FromSlash, 30 | "ext": Ext, 31 | "glob": Glob, 32 | "is_abs": IsAbs, 33 | "join": Join, 34 | "list_separator": ListSeparator, 35 | "match": Match, 36 | "rel": Rel, 37 | "separator": Separator, 38 | "split": Split, 39 | "split_list": SplitList, 40 | "to_slash": ToSlash, 41 | "volume_name": VolumeName, 42 | } 43 | -------------------------------------------------------------------------------- /stats/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local stats = require("stats") 2 | 3 | function Test_median(t) 4 | local result, err = stats.median({ 0, 0, 10 }) 5 | assert(not err, err) 6 | assert(result == 0, "median get: " .. tostring(result)) 7 | end 8 | 9 | function Test_percentile(t) 10 | tests = { 11 | { 12 | name = "100 gets 10", 13 | data = { 0, 0, 10 }, 14 | percentile = 100, 15 | expected = 10, 16 | }, 17 | { 18 | name = "60 gets 0", 19 | data = { 0, 0, 10 }, 20 | percentile = 60, 21 | expected = 0, 22 | }, 23 | } 24 | for _, tt in ipairs(tests) do 25 | t:Run(tt.name, function(t) 26 | local result, err = stats.percentile(tt.data, tt.percentile) 27 | assert(not err, err) 28 | assert(result == tt.expected, "percentile get: " .. tostring(result)) 29 | end) 30 | end 31 | end 32 | 33 | function Test_standard_deviation(t) 34 | local result, err = stats.standard_deviation({ 1, 1, 1, 1 }) 35 | assert(not err, err) 36 | assert(result == 0.5, "standard_deviation get: " .. tostring(result)) 37 | end 38 | -------------------------------------------------------------------------------- /prometheus/client/example_test.go: -------------------------------------------------------------------------------- 1 | package prometheus_client_test 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/vadv/gopher-lua-libs/http" 7 | prometheus "github.com/vadv/gopher-lua-libs/prometheus/client" 8 | "github.com/vadv/gopher-lua-libs/time" 9 | lua "github.com/yuin/gopher-lua" 10 | ) 11 | 12 | // prometheus:start(string) 13 | func ExampleStart() { 14 | state := lua.NewState() 15 | prometheus.Preload(state) 16 | time.Preload(state) 17 | http.Preload(state) 18 | 19 | source := ` 20 | local prometheus = require("prometheus") 21 | local time = require("time") 22 | local http = require("http_client") 23 | 24 | local pp = prometheus.register(":18080") 25 | pp:start() 26 | time.sleep(1) 27 | 28 | local client = http.client({timeout=5}) 29 | 30 | local request = http.request("GET", "http://127.0.0.1:18080/") 31 | local result = client:do_request(request) 32 | print(result.code) 33 | 34 | local request = http.request("GET", "http://127.0.0.1:18080/metrics") 35 | local result = client:do_request(request) 36 | print(result.code) 37 | ` 38 | if err := state.DoString(source); err != nil { 39 | log.Fatal(err.Error()) 40 | } 41 | // Output: 42 | // 404 43 | // 200 44 | } 45 | -------------------------------------------------------------------------------- /examples/slack-alertmanager-silence-bot/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | Let's assume you have such configuration in alertmanager for slack. 4 | ``` 5 | slack_configs: 6 | - channel: "" 7 | api_url: "" 8 | callback_id: 'silence' 9 | title: "[ {{ .GroupLabels.alertname }}: {{ .CommonAnnotations.summary }} ]" 10 | text: '{{ range .Alerts }} {{ .Annotations.description }} {{ "\n" }} {{ end }}' 11 | 12 | actions: 13 | - type: 'button' 14 | text: '{{ if eq .Status "firing" }} Silence for 24 hours {{ else }}{{ end }}' 15 | name: 'silence' # We used that value in bot 16 | style: '{{ if eq .Status "firing" }}danger{{ else }}good{{ end }}' 17 | value: '{{ if eq .Status "firing" }}{"labels": [ {{ range .GroupLabels.SortedPairs }} { "{{ .Name }}": "{{ .Value }}" }, {{ end }} { "alertname": "{{ .GroupLabels.alertname }}" } ], "duration": "24", "url": "{{ .ExternalURL }}" } {{end}}' 18 | 19 | ``` 20 | 21 | Alertmanager uses value as container for pass data to this bot. Field `duration` indicates silence time period in hours. 22 | 23 | Start bot: 24 | ``` 25 | $ GLUA_LOG_SCRIPT_LEVEL=debug glua-libs ./bot.lua 26 | ``` 27 | -------------------------------------------------------------------------------- /tcp/example_test.go: -------------------------------------------------------------------------------- 1 | package tcp 2 | 3 | import ( 4 | "log" 5 | "time" 6 | 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // tcp.open(), tcp_client_ud:write(), tcp_client_ud:read() 11 | func Example_full() { 12 | state := lua.NewState() 13 | Preload(state) 14 | go runPingPongServer(":12346") 15 | time.Sleep(time.Second) 16 | source := ` 17 | local tcp = require("tcp") 18 | 19 | local conn, err = tcp.open(":12346") 20 | if err then error(err) end 21 | 22 | -- send ping, read "pong\n" 23 | local err = conn:write("ping") 24 | if err then error(err) end 25 | local result, err = conn:read() 26 | if err then error(err) end 27 | print(result) 28 | 29 | -- send ping, read by byte 30 | local err = conn:write("ping") 31 | if err then error(err) end 32 | for i = 1, 5 do 33 | local result, err = conn:read(1) 34 | if err then error(err) end 35 | print(result) 36 | end 37 | 38 | conn:close() 39 | ` 40 | if err := state.DoString(source); err != nil { 41 | log.Fatal(err.Error()) 42 | } 43 | // Output: 44 | // pong 45 | // 46 | // p 47 | // o 48 | // n 49 | // g 50 | // 51 | } 52 | -------------------------------------------------------------------------------- /aws/cloudwatch/cloudwatch.go: -------------------------------------------------------------------------------- 1 | // Package cloudwatch implements cloudwatch client api functionality for lua. 2 | package cloudwatch 3 | 4 | import ( 5 | "github.com/aws/aws-sdk-go/aws" 6 | "github.com/aws/aws-sdk-go/aws/session" 7 | "github.com/aws/aws-sdk-go/service/cloudwatch" 8 | "github.com/aws/aws-sdk-go/service/cloudwatchlogs" 9 | lua "github.com/yuin/gopher-lua" 10 | ) 11 | 12 | type luaClW struct { 13 | cloudWatchClient *cloudwatch.CloudWatch 14 | logClient *cloudwatchlogs.CloudWatchLogs 15 | } 16 | 17 | func checkluaClW(L *lua.LState, n int) *luaClW { 18 | ud := L.CheckUserData(1) 19 | if v, ok := ud.Value.(*luaClW); ok { 20 | return v 21 | } 22 | L.ArgError(1, "clw expected") 23 | return nil 24 | } 25 | 26 | func newLauClW(awsProfile *string, awsRegion *string) (*luaClW, error) { 27 | opts := session.Options{ 28 | SharedConfigState: session.SharedConfigEnable, 29 | } 30 | if awsProfile != nil { 31 | opts.Profile = *awsProfile 32 | } 33 | if awsRegion != nil { 34 | opts.Config = aws.Config{Region: awsRegion} 35 | } 36 | sess := session.Must(session.NewSessionWithOptions(opts)) 37 | return &luaClW{ 38 | logClient: cloudwatchlogs.New(sess), 39 | cloudWatchClient: cloudwatch.New(sess), 40 | }, nil 41 | } 42 | -------------------------------------------------------------------------------- /tcp/api_test.go: -------------------------------------------------------------------------------- 1 | package tcp 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/stretchr/testify/require" 6 | "github.com/vadv/gopher-lua-libs/tests" 7 | "io" 8 | "net" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func runPingPongServer(addr string) (io.Closer, error) { 14 | listener, err := net.Listen("tcp", addr) 15 | if err != nil { 16 | return nil, nil 17 | } 18 | 19 | go func() { 20 | for { 21 | conn, err := listener.Accept() 22 | if err != nil { 23 | panic(err) 24 | } 25 | handleTCPClient(conn) 26 | } 27 | }() 28 | 29 | return listener, nil 30 | } 31 | 32 | func handleTCPClient(conn net.Conn) { 33 | buf := make([]byte, 1024) 34 | for { 35 | count, err := conn.Read(buf) 36 | if err != nil { 37 | return 38 | } 39 | data := buf[0:count] 40 | if string(data) == "ping" { 41 | conn.Write([]byte("pong\n")) 42 | } else { 43 | conn.Write([]byte("unknown\n")) 44 | } 45 | } 46 | } 47 | 48 | func TestApi(t *testing.T) { 49 | closer, err := runPingPongServer(":12345") 50 | require.NoError(t, err) 51 | t.Cleanup(func() { 52 | _ = closer.Close() 53 | }) 54 | time.Sleep(time.Second) 55 | 56 | assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua")) 57 | } 58 | -------------------------------------------------------------------------------- /cmd/README.md: -------------------------------------------------------------------------------- 1 | # cmd [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/cmd?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/cmd) 2 | 3 | 4 | ## Functions 5 | `exec(command, [timeout=10])` - execute command via [exec.Start](https://golang.org/pkg/os/exec/#Cmd.Start). Will wait while command is executed. 6 | Returns table with values 7 | - `status` 8 | - `stdout` 9 | - `stderr` 10 | 11 | The default timeout is 10 seconds after which the command will be terminated. The default timeout may be overriden with an optional timeout value (seconds). 12 | 13 | ## Examples 14 | 15 | ```lua 16 | local cmd = require("cmd") 17 | local runtime = require("runtime") 18 | 19 | local command = "sleep 1" 20 | if runtime.goos() == "windows" then command = "timeout 1" end 21 | 22 | local result, err = cmd.exec(command) 23 | if err then error(err) end 24 | if not(result.status == 0) then error("status") end 25 | ``` 26 | 27 | ```lua 28 | local cmd = require("cmd") 29 | local runtime = require("runtime") 30 | 31 | local command = "sleep 5" 32 | if runtime.goos() == "windows" then command = "timeout 1" end 33 | 34 | local result, err = cmd.exec(command, 1) 35 | if err then error(err) end 36 | if not(result.status == 0) then error("status") end 37 | ``` 38 | -------------------------------------------------------------------------------- /tcp/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local tcp = require("tcp") 2 | 3 | function Test_tcp(t) 4 | 5 | local conn, err = tcp.open(":12345") 6 | assert(not err, err) 7 | t:Log("done: tcp:open()") 8 | 9 | local function assert_equal(expected, got) 10 | assert(got == expected, string.format([[expected "%s": got "%s"]], expected, got)) 11 | end 12 | 13 | t:Run("write ping read pong", function(t) 14 | err = conn:write("ping") 15 | assert(not err, err) 16 | t:Log("done: tcp_client_ud:write()") 17 | 18 | local result, err = conn:read("*l") 19 | assert(not err, err) 20 | assert_equal("pong", result) 21 | t:Log("done: tcp_client_ud:read_line()") 22 | end) 23 | 24 | t:Run("read timeout fields", function(t) 25 | assert_equal(5, conn.dialTimeout) 26 | assert_equal(1, conn.writeTimeout) 27 | assert_equal(1, conn.readTimeout) 28 | assert_equal(1, conn.closeTimeout) 29 | end) 30 | 31 | t:Run('write/read timeout fields', function(t) 32 | -- Check setting fields 33 | conn.closeTimeout = 2 34 | assert_equal(2, conn.closeTimeout) 35 | conn.closeTimeout = 0.5 36 | assert_equal(0.5, conn.closeTimeout) 37 | end) 38 | end 39 | -------------------------------------------------------------------------------- /io/README.md: -------------------------------------------------------------------------------- 1 | # Wrappers for golang io 2 | 3 | *NOTE*: These aren't exposed to LUA directly, but used as utilities for other classes, which need 4 | the bridge between lua file and these interfaces: 5 | 6 | - io.Reader 7 | - io.Writer 8 | 9 | See usages of `CheckIOReader` and `CheckIOWriter` in [json](../json) and [yaml](../yaml) modules to treat args as the appropriate go type. 10 | 11 | Going the other way, `ReaderFuncTable` and `WriterFuncTable` are provided for libraries that need to register a 12 | type that behaves like a `io.Reader` or `io.Writer` and may used as a `file` from lua. See example uses of this in the 13 | `strings` and `base64` modules, such as this snippet from [base64](../base64). 14 | 15 | ```go 16 | //registerBase64Encoder Registers the encoder type and its methods 17 | func registerBase64Encoder(L *lua.LState) { 18 | mt := L.NewTypeMetatable(base64EncoderType) 19 | L.SetGlobal(base64EncoderType, mt) 20 | L.SetField(mt, "__index", lio.WriterFuncTable(L)) 21 | } 22 | 23 | //registerBase64Decoder Registers the decoder type and its methods 24 | func registerBase64Decoder(L *lua.LState) { 25 | mt := L.NewTypeMetatable(base64DecoderType) 26 | L.SetGlobal(base64DecoderType, mt) 27 | L.SetField(mt, "__index", lio.ReaderFuncTable(L)) 28 | } 29 | ``` -------------------------------------------------------------------------------- /strings/README.md: -------------------------------------------------------------------------------- 1 | # strings [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/strings?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/strings) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local inspect = require("inspect") 7 | local strings = require("strings") 8 | 9 | -- strings.split(string, sep) 10 | local result = strings.split("a b c d", " ") 11 | print(inspect(result, {newline="", indent=""})) 12 | -- Output: { "a", "b", "c", "d" } 13 | 14 | -- strings.has_prefix(string, prefix) 15 | local result = strings.has_prefix("abcd", "a") 16 | -- Output: true 17 | 18 | -- strings.has_suffix(string, suffix) 19 | local result = strings.has_suffix("abcd", "d") 20 | -- Output: true 21 | 22 | -- strings.trim(string, cutset) 23 | local result = strings.trim("abcd", "d") 24 | -- Output: abc 25 | 26 | -- strings.contains(string, substring) 27 | local result = strings.contains("abcd", "d") 28 | -- Output: true 29 | ``` 30 | 31 | ### Reader/Writer classes often used with json+yaml Encoder/Decoder 32 | 33 | ```lua 34 | reader = strings.new_reader([[{"foo":"bar","baz":"buz"}]]) 35 | assert(reader:read("*a") == [[{"foo":"bar","baz":"buz"}]]) 36 | 37 | writer = strings.new_builder() 38 | writer:write("foo", "bar", 123) 39 | assert(writer:string() == "foobar123") 40 | ``` 41 | -------------------------------------------------------------------------------- /humanize/api.go: -------------------------------------------------------------------------------- 1 | // Port dustin/go-humanize for gopher-lua 2 | package humanize 3 | 4 | import ( 5 | "time" 6 | 7 | humanize "github.com/dustin/go-humanize" 8 | lua "github.com/yuin/gopher-lua" 9 | ) 10 | 11 | // Time lua humanize.time(number) return string 12 | func Time(L *lua.LState) int { 13 | then := time.Unix(L.CheckInt64(1), 0) 14 | L.Push(lua.LString(humanize.Time(then))) 15 | return 1 16 | } 17 | 18 | // IBytes lua humanize.ibytes(number) return string 19 | func IBytes(L *lua.LState) int { 20 | bytes := L.CheckInt64(1) 21 | if bytes < 0 { 22 | L.ArgError(1, "must be positive") 23 | } 24 | L.Push(lua.LString(humanize.IBytes(uint64(bytes)))) 25 | return 1 26 | } 27 | 28 | // ParseBytes lua humanize.parse_bytes(string) returns (number, err) 29 | func ParseBytes(L *lua.LState) int { 30 | data := L.CheckString(1) 31 | size, err := humanize.ParseBytes(data) 32 | if err != nil { 33 | L.Push(lua.LNil) 34 | L.Push(lua.LString(err.Error())) 35 | return 2 36 | } 37 | L.Push(lua.LNumber(size)) 38 | return 1 39 | } 40 | 41 | // SI lua humanize.si(number, string) return string 42 | func SI(L *lua.LState) int { 43 | value := L.CheckNumber(1) 44 | input := float64(value) 45 | unit := L.CheckString(2) 46 | L.Push(lua.LString(humanize.SI(input, unit))) 47 | return 1 48 | } 49 | -------------------------------------------------------------------------------- /pprof/example_test.go: -------------------------------------------------------------------------------- 1 | package pprof_test 2 | 3 | import ( 4 | "log" 5 | 6 | lua_http "github.com/vadv/gopher-lua-libs/http" 7 | lua_pprof "github.com/vadv/gopher-lua-libs/pprof" 8 | lua_time "github.com/vadv/gopher-lua-libs/time" 9 | 10 | lua "github.com/yuin/gopher-lua" 11 | ) 12 | 13 | // pprof:register(), pprof_ud:enable(), pprof_ud:disable() 14 | func Example_package() { 15 | state := lua.NewState() 16 | lua_pprof.Preload(state) 17 | lua_http.Preload(state) 18 | lua_time.Preload(state) 19 | source := ` 20 | local pprof = require("pprof") 21 | local http = require("http") 22 | local time = require("time") 23 | 24 | local client = http.client() 25 | local pp = pprof.register(":1234") 26 | 27 | pp:enable() 28 | time.sleep(1) 29 | 30 | local req, err = http.request("GET", "http://127.0.0.1:1234/debug/pprof/goroutine") 31 | if err then error(err) end 32 | local resp, err = client:do_request(req) 33 | if err then error(err) end 34 | if not(resp.code == 200) then error("resp code") end 35 | print(resp.code) 36 | 37 | pp:disable() 38 | time.sleep(5) 39 | 40 | local resp, err = client:do_request(req) 41 | if not(err) then error("must be error") end 42 | ` 43 | if err := state.DoString(source); err != nil { 44 | log.Fatal(err.Error()) 45 | } 46 | // Output: 47 | // 200 48 | } 49 | -------------------------------------------------------------------------------- /plugin/README.md: -------------------------------------------------------------------------------- 1 | # plugin [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/plugin?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/plugin) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local plugin = require("plugin") 7 | local time = require("time") 8 | 9 | local plugin_body = [[ 10 | local time = require("time") 11 | local i = 1 12 | while true do 13 | print(i) 14 | i = i + 1 15 | time.sleep(1) 16 | end 17 | ]] 18 | 19 | -- plugin.do_string(body) 20 | -- also you can use: plugin.do_file(filename) 21 | local print_plugin = plugin.do_string(plugin_body) 22 | print_plugin:run() 23 | time.sleep(2) 24 | print_plugin:stop() 25 | time.sleep(1) 26 | 27 | local running = print_plugin:is_running() 28 | if running then error("already running") end 29 | -- also you can get last error: print_plugin:error() 30 | 31 | -- plugin.do_string_with_payload() 32 | -- also you can use: plugin.do_file_with_payload(filename) 33 | local job_body = [[ 34 | print(payload) 35 | ]] 36 | local print_plugin_with_payload = plugin.do_string_with_payload(plugin_body, "text of payload") 37 | print_plugin_with_payload:run() 38 | -- must print: "text of payload" 39 | time.sleep(1) 40 | local running = print_plugin:is_running() 41 | if running then error("already running") end 42 | ``` 43 | -------------------------------------------------------------------------------- /storage/example_test.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "log" 5 | 6 | inspect "github.com/vadv/gopher-lua-libs/inspect" 7 | time "github.com/vadv/gopher-lua-libs/time" 8 | 9 | lua "github.com/yuin/gopher-lua" 10 | ) 11 | 12 | // storage.open(), storage_ud:get(), storage_ud:set() 13 | func Example_package() { 14 | state := lua.NewState() 15 | Preload(state) 16 | inspect.Preload(state) 17 | time.Preload(state) 18 | source := ` 19 | local storage = require("storage") 20 | local inspect = require("inspect") 21 | 22 | local s, err = storage.open("./test/db-example.json") 23 | if err then error(err) end 24 | 25 | local err = s:set("key", {"one", "two", 1}, 10) 26 | if err then error(err) end 27 | 28 | local value, found, err = s:get("key") 29 | if err then error(err) end 30 | if not found then error("must be found") end 31 | 32 | print(inspect(value, {newline="", indent=""})) 33 | 34 | local list = s:keys() 35 | print(#list == 1) 36 | 37 | local dump, err = s:dump() 38 | if err then error(err) end 39 | print(inspect(dump, {newline="", indent=""})) 40 | 41 | os.remove("./test/db-example.json") 42 | ` 43 | if err := state.DoString(source); err != nil { 44 | log.Fatal(err.Error()) 45 | } 46 | // Output: 47 | // { "one", "two", 1 } 48 | // true 49 | // {key = { "one", "two", 1 }} 50 | } 51 | -------------------------------------------------------------------------------- /prometheus/client/loader.go: -------------------------------------------------------------------------------- 1 | package prometheus_client 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds prometheus to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local prometheus = require("prometheus") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("prometheus", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | prometheusClient := L.NewTypeMetatable(`prometheus_client_ud`) 19 | L.SetGlobal(`prometheus_client_ud`, prometheusClient) 20 | L.SetField(prometheusClient, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "start": Start, 22 | "stop": Stop, 23 | })) 24 | 25 | prometheusMetricUd := L.NewTypeMetatable(`prometheus_client_metric_ud`) 26 | L.SetGlobal(`prometheus_client_metric_ud`, prometheusMetricUd) 27 | L.SetField(prometheusMetricUd, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 28 | "set": Set, 29 | "add": Add, 30 | "inc": Inc, 31 | })) 32 | 33 | t := L.NewTable() 34 | L.SetFuncs(t, api) 35 | L.Push(t) 36 | return 1 37 | } 38 | 39 | var api = map[string]lua.LGFunction{ 40 | "register": Register, 41 | "counter": Counter, 42 | "gauge": Gauge, 43 | } 44 | -------------------------------------------------------------------------------- /xmlpath/loader.go: -------------------------------------------------------------------------------- 1 | package xmlpath 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds xmlpath to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local xmlpath = require("xmlpath") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("xmlpath", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | node := L.NewTypeMetatable(`xmlpath_node_ud`) 19 | L.SetGlobal(`xmlpath_node_ud`, node) 20 | L.SetField(node, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "string": NodeToString, 22 | })) 23 | 24 | path := L.NewTypeMetatable(`xmlpath_path_ud`) 25 | L.SetGlobal(`xmlpath_path_ud`, path) 26 | L.SetField(path, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 27 | "iter": PathIter, 28 | })) 29 | 30 | iter := L.NewTypeMetatable(`xmlpath_iter_ud`) 31 | L.SetGlobal(`xmlpath_iter_ud`, iter) 32 | L.SetField(iter, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 33 | "node": IterNode, 34 | })) 35 | 36 | t := L.NewTable() 37 | L.SetFuncs(t, api) 38 | L.Push(t) 39 | return 1 40 | } 41 | 42 | var api = map[string]lua.LGFunction{ 43 | "load": Load, 44 | "compile": Compile, 45 | } 46 | -------------------------------------------------------------------------------- /regexp/example_test.go: -------------------------------------------------------------------------------- 1 | package regexp 2 | 3 | import ( 4 | "log" 5 | 6 | inspect "github.com/vadv/gopher-lua-libs/inspect" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // regexp_ud:match(string) 11 | func ExampleMatch() { 12 | state := lua.NewState() 13 | Preload(state) 14 | source := ` 15 | local regexp = require("regexp") 16 | local reg, err = regexp.compile("hello") 17 | if err then error(err) end 18 | local result = reg:match("string: 'hello world'") 19 | print(result) 20 | ` 21 | if err := state.DoString(source); err != nil { 22 | log.Fatal(err.Error()) 23 | } 24 | // Output: 25 | // true 26 | } 27 | 28 | // regexp_ud:find_all_string_submatch(string) 29 | func ExampleFindAllStringSubmatch() { 30 | state := lua.NewState() 31 | Preload(state) 32 | inspect.Preload(state) 33 | source := ` 34 | local regexp = require("regexp") 35 | local inspect = require("inspect") 36 | local reg, err = regexp.compile("string: '(.*)\\s+(.*)'$") 37 | if err then error(err) end 38 | local result = reg:find_all_string_submatch("string: 'hello world'") 39 | print(inspect(result, {newline="", indent=""})) 40 | ` 41 | if err := state.DoString(source); err != nil { 42 | log.Fatal(err.Error()) 43 | } 44 | // Output: 45 | // { { "string: 'hello world'", "hello", "world" } } 46 | } 47 | -------------------------------------------------------------------------------- /http/test/test_server.lua: -------------------------------------------------------------------------------- 1 | local http = require 'http' 2 | local plugin = require 'plugin' 3 | local time = require 'time' 4 | local inspect = require 'inspect' 5 | 6 | function Test_do_handle_function(t) 7 | local addr_ch = channel.make(1) 8 | local server_body = [[ 9 | local addr_ch = unpack(arg) 10 | local http = require 'http' 11 | local server, err = http.server {} 12 | assert(not err, tostring(err)) 13 | addr_ch:send(server:addr()) 14 | server:do_handle_function(function(response, request) 15 | response:code(200) 16 | response:write("OK\n") 17 | response:done() 18 | end) 19 | ]] 20 | local server_plugin = plugin.do_string(server_body, addr_ch) 21 | server_plugin:run() 22 | time.sleep(1) 23 | local server_plugin_error = server_plugin:error() 24 | assert(not server_plugin_error, tostring(server_plugin_error)) 25 | local ok, addr = addr_ch:receive(1) 26 | assert(ok, "addr not ok") 27 | local tURL = string.format("http://%s/", addr) 28 | 29 | local client = http.client() 30 | local req = http.request('GET', tURL) 31 | local resp, err = client:do_request(req) 32 | assert(not err, tostring(err)) 33 | assert(resp.code == 200, tostring(resp.code)) 34 | 35 | server_plugin:stop() 36 | end -------------------------------------------------------------------------------- /ioutil/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local ioutil = require("ioutil") 2 | 3 | local test_data = "test\n" 4 | 5 | function TestWriteRead(t) 6 | t:Run("write_file", function(t) 7 | local err = ioutil.write_file("./test/file.test", test_data) 8 | if err then error(err) end 9 | end) 10 | 11 | t:Run("read_file", function(t) 12 | local data, err = ioutil.read_file("./test/file.test") 13 | if err then error(err) end 14 | if not(data == test_data) then error("ioutil.read_file()") end 15 | _, err = ioutil.read_file("./test/unknown.test") 16 | if err == nil then error("ioutil.read_file() must be error") end 17 | print("done: ioutil.read_file()") 18 | end) 19 | end 20 | 21 | function TestCopy(t) 22 | local input_fh, err = io.open("./test/file.test", "r") 23 | assert(not err, err) 24 | local output_fh, err = io.open("./test/file2.data", "w") 25 | assert(not err, err) 26 | ioutil.copy(output_fh, input_fh) 27 | input_fh:close() 28 | output_fh:close() 29 | 30 | local orig_data, err = ioutil.read_file("./test/file.test") 31 | assert(not err, err) 32 | local copied_data, err = ioutil.read_file("./test/file2.data") 33 | assert(not err, err) 34 | assert(orig_data == copied_data, string.format("'%s' ~= '%s'", orig_data, copied_data)) 35 | end 36 | -------------------------------------------------------------------------------- /strings/builder.go: -------------------------------------------------------------------------------- 1 | package strings 2 | 3 | import ( 4 | lio "github.com/vadv/gopher-lua-libs/io" 5 | lua "github.com/yuin/gopher-lua" 6 | "strings" 7 | ) 8 | 9 | const ( 10 | stringsBuilderType = "strings.Builder" 11 | ) 12 | 13 | func CheckStringsBuilder(L *lua.LState, n int) *strings.Builder { 14 | ud := L.CheckUserData(n) 15 | if builder, ok := ud.Value.(*strings.Builder); ok { 16 | return builder 17 | } 18 | L.ArgError(n, stringsBuilderType+" expected") 19 | return nil 20 | } 21 | 22 | func LVStringsBuilder(L *lua.LState, builder *strings.Builder) lua.LValue { 23 | ud := L.NewUserData() 24 | ud.Value = builder 25 | L.SetMetatable(ud, L.GetTypeMetatable(stringsBuilderType)) 26 | return ud 27 | } 28 | 29 | func stringsBuilderString(L *lua.LState) int { 30 | builder := CheckStringsBuilder(L, 1) 31 | s := builder.String() 32 | L.Push(lua.LString(s)) 33 | return 1 34 | } 35 | 36 | func newStringsBuilder(L *lua.LState) int { 37 | builder := &strings.Builder{} 38 | L.Push(LVStringsBuilder(L, builder)) 39 | return 1 40 | } 41 | 42 | func registerStringsBuilder(L *lua.LState) lua.LValue { 43 | mt := L.NewTypeMetatable(stringsBuilderType) 44 | writerTable := lio.WriterFuncTable(L) 45 | L.SetField(writerTable, "string", L.NewFunction(stringsBuilderString)) 46 | L.SetField(mt, "__index", writerTable) 47 | return mt 48 | } 49 | -------------------------------------------------------------------------------- /prometheus/client/metric_config.go: -------------------------------------------------------------------------------- 1 | package prometheus_client 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/prometheus/client_golang/prometheus" 8 | ) 9 | 10 | type promMetricConfig struct { 11 | namespace string 12 | name string 13 | subsystem string 14 | help string 15 | labels []string 16 | } 17 | 18 | func (m *promMetricConfig) hasLabels() bool { 19 | return len(m.labels) > 0 20 | } 21 | 22 | func (m *promMetricConfig) getKey() string { 23 | return fmt.Sprintf("%s_%s_%s", m.namespace, m.subsystem, m.name) 24 | } 25 | 26 | func (m *promMetricConfig) equal(m2 *promMetricConfig) bool { 27 | if m.getKey() != m2.getKey() { 28 | return false 29 | } 30 | if (len(m.labels) != 0) && (len(m2.labels) != 0) { 31 | // because labels sorted 32 | return strings.Join(m.labels, "") == strings.Join(m2.labels, "") 33 | } 34 | return false 35 | } 36 | 37 | func (m *promMetricConfig) getGaugeOpts() prometheus.GaugeOpts { 38 | return prometheus.GaugeOpts{ 39 | Namespace: m.namespace, 40 | Subsystem: m.subsystem, 41 | Name: m.name, 42 | Help: m.help, 43 | } 44 | } 45 | 46 | func (m *promMetricConfig) getCounterOpts() prometheus.CounterOpts { 47 | return prometheus.CounterOpts{ 48 | Namespace: m.namespace, 49 | Subsystem: m.subsystem, 50 | Name: m.name, 51 | Help: m.help, 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /http/client/loader.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | // Package http_client implements golang package http_client utility functionality for lua. 4 | 5 | import ( 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // Preload adds http_client to the given Lua state's package.preload table. After it 10 | // has been preloaded, it can be loaded using require: 11 | // 12 | // local http_client = require("http_client") 13 | func Preload(L *lua.LState) { 14 | L.PreloadModule("http_client", Loader) 15 | } 16 | 17 | // Loader is the module loader function. 18 | func Loader(L *lua.LState) int { 19 | 20 | http_client_ud := L.NewTypeMetatable(`http_client_ud`) 21 | L.SetGlobal(`http_client_ud`, http_client_ud) 22 | L.SetField(http_client_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 23 | "do_request": DoRequest, 24 | })) 25 | 26 | http_request_ud := L.NewTypeMetatable(`http_request_ud`) 27 | L.SetGlobal(luaRequestType, http_request_ud) 28 | L.SetField(http_request_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 29 | "set_basic_auth": SetBasicAuth, 30 | "header_set": HeaderSet, 31 | })) 32 | 33 | t := L.NewTable() 34 | L.SetFuncs(t, api) 35 | L.Push(t) 36 | return 1 37 | } 38 | 39 | var api = map[string]lua.LGFunction{ 40 | "client": New, 41 | "request": NewRequest, 42 | "file_request": NewFileRequest, 43 | } 44 | -------------------------------------------------------------------------------- /tests/data/zabbix3/ssl/nginx.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDgjCCAmqgAwIBAgIJAIxUwcTC4O7CMA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV 3 | BAYTAlJVMSUwIwYJKoZIhvcNAQkBFhZtYWtzaW03N3N0ZXJAZ21haWwuY29tMB4X 4 | DTE2MDQyMDA2MzUxNFoXDTE3MDQyMDA2MzUxNFowNDELMAkGA1UEBhMCUlUxJTAj 5 | BgkqhkiG9w0BCQEWFm1ha3NpbTc3c3RlckBnbWFpbC5jb20wggEiMA0GCSqGSIb3 6 | DQEBAQUAA4IBDwAwggEKAoIBAQChO7tds/j0QNpk/kslvxvpIlSHSnLPNo/F8rUJ 7 | KkXx9la/1obNF6N1Atk0olQVOf+oCcdY8sZy/V1PpH7Coeb0YxYgnft+Ca8m6qbB 8 | t/2yXq/4P8w+QnVHEzS5Tt68GBelpUXA4LbdoeN3uYASLdlY95+coCDZoZSvnqtj 9 | kk2HTONnPyDmUnaA8bQna2WVud5cXBpCEHRmMYnLOwhvhzxDjXEX1LFl+kvx1Lof 10 | F5K4FhSGGqGpIJEWeQ/EOowpNIffZIDDxvW2Bwy/HTeJBxI94nH5UqZtmeMbHzBP 11 | Qnm3HKtGnaZx4ULzaSmymN50x4UlnqFNrH+oqPJzN/ZjlU8NAgMBAAGjgZYwgZMw 12 | HQYDVR0OBBYEFFGqvaOMlScHMeayzOuuPTbJX6h1MGQGA1UdIwRdMFuAFFGqvaOM 13 | lScHMeayzOuuPTbJX6h1oTikNjA0MQswCQYDVQQGEwJSVTElMCMGCSqGSIb3DQEJ 14 | ARYWbWFrc2ltNzdzdGVyQGdtYWlsLmNvbYIJAIxUwcTC4O7CMAwGA1UdEwQFMAMB 15 | Af8wDQYJKoZIhvcNAQEFBQADggEBAEsqPk4sf18sMrmGooR3d8xVZpkfm8Uyh5/J 16 | 0rRHHuXllQAWta17TwGn8LdapAyVOlTYzsIBZ2clIOUwlTZOJdJv9d0tAgiLwZ0q 17 | zDN57jYGcOpyJA5EzdnmzQA5RafYZh4bSLAvarRExR4jFRUzJ+/KqoNWl/EpApPo 18 | HkowZtzVrhEpqZoufzAvq5p1Gj95IGFKfKynBcpOoatyVZ8Y9f0D2Wb9VOxlbvG0 19 | qP7FfayGphAP7lnGJyPwszYhRozT3a6FEdqICTAaBpDJCIrMzxcHJadwb1KfQOVs 20 | X4rx418l999n8d6ssEqEWNvnV8ET3iV+JYmtbIOkQn5UZV20PqQ= 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /pprof/api.go: -------------------------------------------------------------------------------- 1 | // Package pprof implements golang package pprof functionality. 2 | package pprof 3 | 4 | import ( 5 | "context" 6 | "net/http" 7 | _ "net/http/pprof" 8 | "time" 9 | 10 | lua "github.com/yuin/gopher-lua" 11 | ) 12 | 13 | type luaPprof struct { 14 | addr string 15 | stop chan bool 16 | } 17 | 18 | func checkPprof(L *lua.LState, n int) *luaPprof { 19 | ud := L.CheckUserData(n) 20 | if v, ok := ud.Value.(*luaPprof); ok { 21 | return v 22 | } 23 | L.ArgError(n, "pprof_ud expected") 24 | return nil 25 | } 26 | 27 | // Register(string): return (pprof_ud, err) 28 | func Register(L *lua.LState) int { 29 | addr := L.CheckString(1) 30 | ud := L.NewUserData() 31 | ud.Value = &luaPprof{addr: addr, stop: make(chan bool, 1)} 32 | L.SetMetatable(ud, L.GetTypeMetatable(`pprof_ud`)) 33 | L.Push(ud) 34 | return 1 35 | } 36 | 37 | // Enable start pprof 38 | func Enable(L *lua.LState) int { 39 | pp := checkPprof(L, 1) 40 | go func() { 41 | h := &http.Server{Addr: pp.addr} 42 | go func() { 43 | if err := h.ListenAndServe(); err != nil { 44 | return 45 | } 46 | }() 47 | <-pp.stop 48 | ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) 49 | h.Shutdown(ctx) 50 | }() 51 | return 0 52 | } 53 | 54 | // Disable pprof stop 55 | func Disable(L *lua.LState) int { 56 | pp := checkPprof(L, 1) 57 | pp.stop <- true 58 | return 0 59 | } 60 | -------------------------------------------------------------------------------- /zabbix/README.md: -------------------------------------------------------------------------------- 1 | # zabbix [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/zabbix?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/zabbix) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local zabbix = require("zabbix") 7 | local inspect = require("inspect") 8 | local http = require("http") 9 | 10 | local client = http.client({proxy="http://proxy", insecure_ssl=true, basic_auth_user="", basic_auth_password=""}) -- override default http client 11 | local zbx = zabbix.new({url="https://zabbix.url"}, client) 12 | 13 | local err = zbx:login() 14 | if err then error(err) end 15 | 16 | local response, err = zbx:request("trigger.get", 17 | { 18 | selectHosts = "extend", selectItems = "extend", selectLastEvent="extend", 19 | output = "extend", sortfield = "priority", 20 | filter = { 21 | sortorder="DESC", value="1", status=0 22 | }, 23 | expandData = "1" 24 | } 25 | ) 26 | if err then error(err) end 27 | 28 | local item_id = 0 29 | for k, v in pairs(response) do 30 | if v.hosts and v.hosts[1] and v.items and v.items[1] and v.items[1].value_type == "3" then 31 | -- print(inspect(v)) 32 | item_id = v.items[1].itemid 33 | print(v.hosts[1].host, v.description) 34 | end 35 | end 36 | 37 | local err = zbx:save_graph(item_id, "./test/test.png") 38 | if err then error(err) end 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /zabbix/example_test.go: -------------------------------------------------------------------------------- 1 | package zabbix_test 2 | 3 | import ( 4 | "log" 5 | 6 | http "github.com/vadv/gopher-lua-libs/http" 7 | inspect "github.com/vadv/gopher-lua-libs/inspect" 8 | zabbix "github.com/vadv/gopher-lua-libs/zabbix" 9 | lua "github.com/yuin/gopher-lua" 10 | ) 11 | 12 | // example zabbix 13 | func Example_package() { 14 | state := lua.NewState() 15 | zabbix.Preload(state) 16 | http.Preload(state) 17 | inspect.Preload(state) 18 | source := ` 19 | local zabbix = require("zabbix") 20 | local inspect = require("inspect") 21 | local http = require("http") 22 | 23 | local client = http.client({proxy="http://proxy"}) 24 | local zbx = zabbix.new({url="http://zabbix.url"}, client) 25 | 26 | 27 | local err = zbx:login() 28 | -- if err then error(err) end 29 | 30 | local response, err = zbx:request("trigger.get", 31 | { 32 | selectHosts = "extend", selectItems = "extend", selectLastEvent="extend", 33 | output = "extend", sortfield = "priority", 34 | filter = { 35 | sortorder="DESC", value="1", status=0 36 | }, 37 | expandData = "1" 38 | } 39 | ) 40 | -- if err then error(err) end 41 | 42 | for k, v in pairs( response ) do 43 | print(inspect(v)) 44 | print(v.description) 45 | end 46 | zbx:logout() 47 | ` 48 | if err := state.DoString(source); err != nil { 49 | log.Fatal(err.Error()) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /log/loader.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | _ "embed" 5 | lua "github.com/yuin/gopher-lua" 6 | ) 7 | 8 | //go:embed loglevel.lua 9 | var lua_loglevel string 10 | 11 | // Preload adds log to the given Lua state's package.preload table. After it 12 | // has been preloaded, it can be loaded using require: 13 | // 14 | // local log = require("log") 15 | // or for levelled logging 16 | // local log = require("loglevel") 17 | func Preload(L *lua.LState) { 18 | L.PreloadModule("log", Loader) 19 | L.PreloadModule("loglevel", LoadLogLevel) 20 | } 21 | 22 | func LoadLogLevel(L *lua.LState) int { 23 | if err := L.DoString(lua_loglevel); err != nil { 24 | L.RaiseError("load library 'loglevel' error: %s", err.Error()) 25 | } 26 | return 1 27 | } 28 | 29 | // Loader is the module loader function. 30 | func Loader(L *lua.LState) int { 31 | 32 | loggerUD := L.NewTypeMetatable(`logger_ud`) 33 | L.SetGlobal(`logger_ud`, loggerUD) 34 | L.SetField(loggerUD, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 35 | "set_output": SetOutput, 36 | "set_prefix": SetPrefix, 37 | "set_flags": SetFlags, 38 | "print": Print, 39 | "printf": Printf, 40 | "println": Println, 41 | "close": Close, 42 | })) 43 | 44 | t := L.NewTable() 45 | L.SetFuncs(t, api) 46 | L.Push(t) 47 | return 1 48 | } 49 | 50 | var api = map[string]lua.LGFunction{ 51 | "new": New, 52 | } 53 | -------------------------------------------------------------------------------- /cert_util/api.go: -------------------------------------------------------------------------------- 1 | // Package cert_utils provides utility for checking ssl-certs in lua. 2 | package cert_util 3 | 4 | import ( 5 | "crypto/tls" 6 | "fmt" 7 | "net" 8 | "time" 9 | 10 | lua "github.com/yuin/gopher-lua" 11 | ) 12 | 13 | // NotAfter lua cert.not_after(hostname, ) returns (unixts cert_not_after, err) 14 | func NotAfter(L *lua.LState) int { 15 | serverName, address := L.CheckString(1), "" 16 | if L.GetTop() > 1 { 17 | address = L.CheckString(2) 18 | } else { 19 | address = fmt.Sprintf("%s:443", serverName) 20 | } 21 | conn, err := net.DialTimeout(`tcp`, address, 5*time.Second) 22 | if err != nil { 23 | L.Push(lua.LNil) 24 | L.Push(lua.LString(err.Error())) 25 | return 2 26 | } 27 | 28 | client := tls.Client(conn, &tls.Config{ServerName: serverName, InsecureSkipVerify: true}) 29 | handshakeErr := client.Handshake() 30 | 31 | var minNotAfter *time.Time 32 | for _, cert := range client.ConnectionState().PeerCertificates { 33 | if minNotAfter == nil || minNotAfter.Unix() > cert.NotAfter.Unix() { 34 | minNotAfter = &cert.NotAfter 35 | } 36 | } 37 | 38 | if minNotAfter == nil { 39 | L.Push(lua.LNil) 40 | L.Push(lua.LString("certs not found")) 41 | return 2 42 | } 43 | 44 | L.Push(lua.LNumber(minNotAfter.Unix())) 45 | if handshakeErr == nil { 46 | L.Push(lua.LNil) 47 | } else { 48 | L.Push(lua.LString(handshakeErr.Error())) 49 | } 50 | return 2 51 | } 52 | -------------------------------------------------------------------------------- /hex/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local hex = require 'hex' 2 | local strings = require 'strings' 3 | local assert = require 'assert' 4 | 5 | function TestHexCodec(t) 6 | local tests = { 7 | { 8 | encoded = "48656c6c6f20776f726c64", -- "Hello world" in hex 9 | decoded = "Hello world", 10 | }, 11 | { 12 | encoded = "", 13 | decoded = "", 14 | }, 15 | } 16 | for _, tt in ipairs(tests) do 17 | t:Run("hex.decode_string(" .. tostring(tt.encoded) .. ")", function(t) 18 | local got = hex.decode_string(tt.encoded) 19 | assert:Equal(t, tt.decoded, got) 20 | end) 21 | 22 | t:Run("hex.encode_to_string(" .. tostring(tt.decoded) .. ")", function(t) 23 | local got = hex.encode_to_string(tt.decoded) 24 | assert:Equal(t, tt.encoded, got) 25 | end) 26 | end 27 | end 28 | 29 | function TestEncoder(t) 30 | local writer = strings.new_builder() 31 | local encoder = hex.new_encoder(writer) 32 | encoder:write("foo", "bar", "baz") 33 | encoder:close() 34 | local s = writer:string() 35 | assert:Equal(t, "666f6f62617262617a", s) 36 | end 37 | 38 | function TestDecoder(t) 39 | local reader = strings.new_reader("666f6f62617262617a") 40 | local decoder = hex.new_decoder(reader) 41 | local s = decoder:read("*a") 42 | assert:Equal(t, "foobarbaz", s) 43 | end 44 | -------------------------------------------------------------------------------- /prometheus/client/utils.go: -------------------------------------------------------------------------------- 1 | package prometheus_client 2 | 3 | import ( 4 | "sort" 5 | 6 | "github.com/prometheus/client_golang/prometheus" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // convert lua table to promMetricConfig 11 | func luaTableToMetricConfig(config *lua.LTable, L *lua.LState) *promMetricConfig { 12 | result := &promMetricConfig{} 13 | config.ForEach(func(k lua.LValue, v lua.LValue) { 14 | switch k.String() { 15 | case `namespace`: 16 | result.namespace = v.String() 17 | case `subsystem`: 18 | result.subsystem = v.String() 19 | case `name`: 20 | result.name = v.String() 21 | case `help`: 22 | result.help = v.String() 23 | case `labels`: 24 | tbl, ok := v.(*lua.LTable) 25 | if !ok { 26 | L.ArgError(1, "labels must be string") 27 | } 28 | result.labels = luaTableToSlice(tbl) 29 | } 30 | }) 31 | return result 32 | } 33 | 34 | // convert lua table to sorted []string 35 | func luaTableToSlice(tbl *lua.LTable) []string { 36 | result := make([]string, 0) 37 | tbl.ForEach(func(k lua.LValue, v lua.LValue) { 38 | result = append(result, v.String()) 39 | }) 40 | sort.Strings(result) 41 | return result 42 | } 43 | 44 | //convert lua table to prometheus.Label 45 | func luaTableToPrometheusLabels(tbl *lua.LTable) prometheus.Labels { 46 | result := make(map[string]string, 0) 47 | tbl.ForEach(func(k lua.LValue, v lua.LValue) { 48 | result[k.String()] = v.String() 49 | }) 50 | return result 51 | } 52 | -------------------------------------------------------------------------------- /aws/cloudwatch/README.md: -------------------------------------------------------------------------------- 1 | # cloudwatch [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/aws/cloudwatch?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/aws/cloudwatch) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local cloudwatch = require("cloudwatch") 7 | 8 | local clw_client, err = cloudwatch.new() 9 | if err then error(err) end 10 | 11 | local filter = { 12 | log_group_name = "group-name", 13 | -- filter_patern = "", 14 | start_time = 1557948000, 15 | end_time = 1557948200, 16 | } 17 | local timeout_sec = 100 18 | local err = clw_client:download("download.log", filter, timeout_sec) 19 | if err then error(err) end 20 | 21 | local query = { 22 | namespace = "AWS/RDS", 23 | metric = "CPUUtilization", 24 | dimension_name = "DBInstanceIdentifier", 25 | dimension_value = "hostname", 26 | stat = "Average", 27 | period = 60, 28 | } 29 | local result, err = clw_client:get_metric_data({start_time=1557948000, end_time=1557948200, queries={cpu=query}}) 30 | if err then error(err) end 31 | print(inspect(result)) 32 | --[[ 33 | { 34 | cpu = { 35 | 1569880560 = 5.72916666666667, 36 | 1569880620 = 4.29166666666667, 37 | 1569880680 = 4.29583333308498, 38 | 1569880740 = 6.44166666641831, 39 | 1569880800 = 9.30833333358169, 40 | 1569880860 = 5.72500000024835, 41 | 1569880920 = 4.29583333308498, 42 | 1569880980 = 4.29583333308498, 43 | 1569881040 = 5.72500000024835 44 | }, 45 | } 46 | --]] 47 | ``` 48 | -------------------------------------------------------------------------------- /json/example_test.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "log" 5 | 6 | inspect "github.com/vadv/gopher-lua-libs/inspect" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // json.decode(string) 11 | func ExampleDecode() { 12 | state := lua.NewState() 13 | Preload(state) 14 | inspect.Preload(state) 15 | source := ` 16 | local json = require("json") 17 | local inspect = require("inspect") 18 | local jsonString = [[{"a":{"b":1}}]] 19 | local result, err = json.decode(jsonString) 20 | if err then error(err) end 21 | local remove_all_metatables = function(item, path) 22 | if path[#path] ~= inspect.METATABLE then return item end 23 | end 24 | print(inspect(result, {process = remove_all_metatables, newline="", indent=""})) 25 | ` 26 | if err := state.DoString(source); err != nil { 27 | log.Fatal(err.Error()) 28 | } 29 | // Output: 30 | // {a = {b = 1}} 31 | } 32 | 33 | // json.encode(obj) 34 | func ExampleEncode() { 35 | state := lua.NewState() 36 | Preload(state) 37 | inspect.Preload(state) 38 | source := ` 39 | local json = require("json") 40 | local inspect = require("inspect") 41 | local table = {a={b=1}} 42 | local result, err = json.encode(table) 43 | if err then error(err) end 44 | print(inspect(result, {newline="", indent=""})) 45 | 46 | print(inspect( json.encode( {} ) )) 47 | ` 48 | if err := state.DoString(source); err != nil { 49 | log.Fatal(err.Error()) 50 | } 51 | // Output: 52 | // '{"a":{"b":1}}' 53 | // "[]" 54 | } 55 | -------------------------------------------------------------------------------- /chef/body.go: -------------------------------------------------------------------------------- 1 | package chef 2 | 3 | import ( 4 | "bytes" 5 | "crypto/sha1" 6 | "encoding/base64" 7 | "encoding/json" 8 | "io" 9 | "log" 10 | "net/http" 11 | ) 12 | 13 | // luaBody wraps io.Reader and adds methods for calculating hashes and detecting content 14 | type luaBody struct { 15 | io.Reader 16 | } 17 | 18 | // contentType returns the content-type string of luaBody as detected by http.DetectContentType() 19 | func (body *luaBody) contentType() string { 20 | if json.Unmarshal(body.buffer().Bytes(), &struct{}{}) == nil { 21 | return "application/json" 22 | } 23 | return http.DetectContentType(body.buffer().Bytes()) 24 | } 25 | 26 | // hash calculates the body content hash 27 | func (body *luaBody) hash() (h string) { 28 | b := body.buffer() 29 | // empty buffs should return a empty string 30 | if b.Len() == 0 { 31 | h = hashStr("") 32 | } 33 | h = hashStr(b.String()) 34 | return 35 | } 36 | 37 | // hashStr returns the base64 encoded SHA1 sum of the toHash string 38 | func hashStr(toHash string) string { 39 | h := sha1.New() 40 | io.WriteString(h, toHash) 41 | hashed := base64.StdEncoding.EncodeToString(h.Sum(nil)) 42 | return hashed 43 | } 44 | 45 | // buffer creates a byte.buffer copy from a io.Reader resets read on reader to 0,0 46 | func (body *luaBody) buffer() *bytes.Buffer { 47 | var b bytes.Buffer 48 | if body.Reader == nil { 49 | return &b 50 | } 51 | 52 | b.ReadFrom(body.Reader) 53 | _, err := body.Reader.(io.Seeker).Seek(0, 0) 54 | if err != nil { 55 | log.Fatal(err) 56 | } 57 | return &b 58 | } 59 | -------------------------------------------------------------------------------- /http/client/client_example_test.go: -------------------------------------------------------------------------------- 1 | package http_test 2 | 3 | import ( 4 | "log" 5 | 6 | http "github.com/vadv/gopher-lua-libs/http" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // http_client_ud:do_request(request) 11 | func ExampleDoRequest() { 12 | state := lua.NewState() 13 | http.Preload(state) 14 | source := ` 15 | local http = require("http") 16 | local client = http.client() 17 | local request = http.request("GET", "https://google.com") 18 | local result, err = client:do_request(request) 19 | if err then error(err) end 20 | print(result.code) 21 | ` 22 | if err := state.DoString(source); err != nil { 23 | log.Fatal(err.Error()) 24 | } 25 | // Output: 26 | // 200 27 | } 28 | 29 | // http:query_escape(string) 30 | func ExampleQueryEscape() { 31 | state := lua.NewState() 32 | http.Preload(state) 33 | source := ` 34 | local http = require("http") 35 | local result = http.query_escape("<> 123") 36 | print(result) 37 | ` 38 | if err := state.DoString(source); err != nil { 39 | log.Fatal(err.Error()) 40 | } 41 | // Output: 42 | // %3C%3E+123 43 | } 44 | 45 | // http:query_escape(string) 46 | func ExampleQueryUnescape() { 47 | state := lua.NewState() 48 | http.Preload(state) 49 | source := ` 50 | local http = require("http") 51 | local result, err = http.query_unescape("%3C%3E+123") 52 | if err then error(err) end 53 | print(result) 54 | ` 55 | if err := state.DoString(source); err != nil { 56 | log.Fatal(err.Error()) 57 | } 58 | // Output: 59 | // <> 123 60 | } 61 | -------------------------------------------------------------------------------- /base64/README.md: -------------------------------------------------------------------------------- 1 | # base64 [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/base64?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/base64) 2 | 3 | Lua module for [encoding/base64](https://pkg.go.dev/encoding/base64) 4 | 5 | ## Usage 6 | 7 | ### Encoding 8 | 9 | ```lua 10 | local base64 = require("base64") 11 | 12 | s = base64.RawStdEncoding:encode_to_string("foo\01bar") 13 | print(s) 14 | Zm9vAWJhcg 15 | 16 | s = base64.StdEncoding:encode_to_string("foo\01bar") 17 | print(s) 18 | Zm9vAWJhcg== 19 | 20 | s = base64.RawURLEncoding:encode_to_string("this is a and should be encoded") 21 | print(s) 22 | dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA 23 | 24 | s = base64.URLEncoding:encode_to_string("this is a and should be encoded") 25 | print(s) 26 | dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA== 27 | 28 | ``` 29 | 30 | ### Decoding 31 | 32 | ```lua 33 | local base64 = require("base64") 34 | 35 | s, err = base64.RawStdEncoding:decode_string("Zm9vAWJhcg") 36 | assert(not err, err) 37 | print(s) 38 | foobar 39 | 40 | s, err = base64.StdEncoding:decode_string("Zm9vAWJhcg==") 41 | assert(not err, err) 42 | print(s) 43 | foobar 44 | 45 | s, err = base64.RawURLEncoding:decode_string("dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA") 46 | assert(not err, err) 47 | print(s) 48 | this is a and should be encoded 49 | 50 | s, err = base64.URLEncoding:decode_string("dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA==") 51 | assert(not err, err) 52 | print(s) 53 | this is a and should be encoded 54 | ``` 55 | -------------------------------------------------------------------------------- /goos/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local goos = require("goos") 2 | 3 | function Test_stat(t) 4 | local info, err = goos.stat("./test/test.file") 5 | assert(not err, err) 6 | assert(info.is_dir == false, "is dir") 7 | assert(0 == info.size, "non-zero size: " .. info.size) 8 | assert(info.mod_time > 0, "mod_time: " .. info.mod_time) 9 | assert(info.mode > "", "mode: " .. info.mode) 10 | end 11 | 12 | function Test_hostname(t) 13 | -- hostname 14 | local hostname, err = goos.hostname() 15 | assert(not err, err) 16 | assert(hostname > "", "hostname") 17 | end 18 | 19 | function Test_pagesize(t) 20 | assert(goos.get_pagesize() > 0, "pagesize") 21 | end 22 | 23 | function Test_environ(t) 24 | local env = goos.environ() 25 | assert(env, "environ should return table") 26 | -- Check that we get a table with environment variables 27 | local count = 0 28 | for k, v in pairs(env) do 29 | count = count + 1 30 | assert(type(k) == "string", "key should be string") 31 | assert(type(v) == "string", "value should be string") 32 | end 33 | assert(count > 0, "environ should return at least one environment variable") 34 | -- PATH should exist on most systems 35 | assert(env.PATH or env.Path, "PATH environment variable should exist") 36 | -- Test environment variable with equals sign in value 37 | assert(env.ENV_VAR == "TEST=1", "ENV_VAR should be TEST=1") 38 | -- Test environment variable with empty value 39 | assert(env.EMPTY_VAR == "", "EMPTY_VAR should be empty string") 40 | end 41 | -------------------------------------------------------------------------------- /time/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local time = require("time") 2 | 3 | function Test_time(t) 4 | t:Run("time.unix", function(t) 5 | local lua_before = os.clock() 6 | local before = time.unix() 7 | t:Logf("lua_before=%f, before=%f", lua_before, before) 8 | time.sleep(2) 9 | local after = time.unix() 10 | local lua_after = os.clock() 11 | t:Logf("lua_after=%f, after=%f", lua_after, after) 12 | assert(after - before >= 1, "time.unix()") 13 | assert(lua_after - lua_before >= 2, "time.sleep()") 14 | end) 15 | 16 | t:Run("parse ok", function(t) 17 | local parse, err = time.parse("Dec 2 03:33:05 2018", "Jan 2 15:04:05 2006") 18 | assert(not err, err) 19 | assert(parse == 1543721585, "time.parse(): 1") 20 | end) 21 | 22 | t:Run("parse with timezone", function(t) 23 | local parse, err = time.parse("Dec 2 03:33:05 2018", "Jan 2 15:04:05 2006", "Asia/Shanghai") 24 | assert(not err, err) 25 | assert(parse == 1543721585 - 8 * 3600, "time.parse(): 3") 26 | end) 27 | 28 | t:Run("parse with error", function(t) 29 | local _, err = time.parse("Dec 32 03:33:05 2018", "Jan 2 15:04:05 2006") 30 | assert(err, "time.parse(): must be error") 31 | end) 32 | 33 | t:Run("format", function(t) 34 | local result, err = time.format(1543721585, "Jan 2 15:04:05 2006", "Europe/Moscow") 35 | assert(not err, err) 36 | assert(result == "Dec 2 06:33:05 2018", "time.format() was " .. result) 37 | end) 38 | end 39 | -------------------------------------------------------------------------------- /log/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local log = require("log") 2 | local ioutil = require("ioutil") 3 | 4 | function Test_log(t) 5 | os.remove("./test/test.log") 6 | 7 | local info, err = log.new("./test/test.log") 8 | assert(not err, err) 9 | 10 | t:Run("write logs", function(t) 11 | info:println("1", 2) 12 | 13 | -- check set prefix 14 | info:set_prefix("[INFO] ") 15 | info:printf("%s %.2f", "1", 2.2) 16 | 17 | -- check flags 18 | info:set_flags({ longfile = true }) 19 | info:printf("ok\n") 20 | info:print("ok") 21 | info:println("ok") 22 | 23 | local err = info:close() 24 | assert(not err, err) 25 | end) 26 | 27 | t:Run("check result", function(t) 28 | local expect_result = [[1 2 29 | [INFO] 1 2.20 30 | [INFO] ./test/test_api.lua:19: ok 31 | [INFO] ./test/test_api.lua:20: ok 32 | [INFO] ./test/test_api.lua:21: ok 33 | ]] 34 | 35 | local get_result, err = ioutil.read_file("./test/test.log") 36 | assert(not err, err) 37 | assert(expect_result == get_result, string.format("expected %s; got %s", expect_result, get_result)) 38 | end) 39 | end 40 | 41 | function TestSetOutput(t) 42 | -- Ensure that set_output does not result in an error 43 | os.remove("./test/test.log") 44 | local info = log.new('STDERR') 45 | info:set_output("./test/test.log") 46 | info:print("foo bar") 47 | info:close() 48 | local get_result, err = ioutil.read_file("./test/test.log") 49 | assert(not err, err) 50 | assert(get_result == 'foo bar\n') 51 | end -------------------------------------------------------------------------------- /db/api_postgres.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "database/sql" 5 | "sync" 6 | 7 | _ "github.com/lib/pq" 8 | ) 9 | 10 | type luaPG struct { 11 | config *dbConfig 12 | sync.Mutex 13 | db *sql.DB 14 | } 15 | 16 | func init() { 17 | RegisterDriver(`postgres`, &luaPG{}) 18 | } 19 | 20 | var ( 21 | sharedPG = make(map[string]*luaPG, 0) 22 | sharedPGLock = &sync.Mutex{} 23 | ) 24 | 25 | func (pg *luaPG) constructor(config *dbConfig) (luaDB, error) { 26 | 27 | sharedPGLock.Lock() 28 | defer sharedPGLock.Unlock() 29 | 30 | if config.sharedMode { 31 | result, ok := sharedPG[config.connString] 32 | if ok { 33 | return result, nil 34 | } 35 | } 36 | 37 | db, err := sql.Open(`postgres`, config.connString) 38 | if err != nil { 39 | return nil, err 40 | } 41 | result := &luaPG{config: config} 42 | db.SetMaxIdleConns(config.maxOpenConns) 43 | db.SetMaxOpenConns(config.maxOpenConns) 44 | result.db = db 45 | 46 | if config.sharedMode { 47 | sharedPG[config.connString] = result 48 | } 49 | 50 | return result, nil 51 | } 52 | 53 | func (pg *luaPG) getTXOptions() *sql.TxOptions { 54 | return &sql.TxOptions{ReadOnly: pg.config.readOnly} 55 | } 56 | 57 | func (pg *luaPG) getDB() *sql.DB { 58 | pg.Lock() 59 | defer pg.Unlock() 60 | return pg.db 61 | } 62 | 63 | func (pg *luaPG) closeDB() error { 64 | pg.Lock() 65 | defer pg.Unlock() 66 | err := pg.db.Close() 67 | if err != nil { 68 | return err 69 | } 70 | if pg.config.sharedMode { 71 | sharedPGLock.Lock() 72 | delete(sharedPG, pg.config.connString) 73 | sharedPGLock.Unlock() 74 | } 75 | return nil 76 | } 77 | -------------------------------------------------------------------------------- /log/logger_config.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | type luaLoggerOutputConfig struct { 11 | date bool 12 | time bool 13 | microseconds bool 14 | utc bool 15 | longfile bool 16 | } 17 | 18 | func parseConfig(L *lua.LState, luaTable *lua.LTable) *luaLoggerOutputConfig { 19 | config := &luaLoggerOutputConfig{} 20 | parseBool := func(L *lua.LState, luaTable *lua.LTable, key string) bool { 21 | if val1 := luaTable.RawGetString(key); val1.Type() != lua.LTNil { 22 | if val2, ok := val1.(lua.LBool); ok { 23 | return bool(val2) 24 | } else { 25 | L.ArgError(1, fmt.Sprintf("%s: must be bool", key)) 26 | } 27 | } 28 | return false 29 | } 30 | config.date = parseBool(L, luaTable, `date`) 31 | config.time = parseBool(L, luaTable, `time`) 32 | config.microseconds = parseBool(L, luaTable, `microseconds`) 33 | config.utc = parseBool(L, luaTable, `utc`) 34 | config.longfile = parseBool(L, luaTable, `longfile`) 35 | return config 36 | } 37 | 38 | func setLogFlags(logger *luaLogger) { 39 | goFlag := 0 40 | if logger.config.date { 41 | goFlag = log.Ldate 42 | } 43 | if logger.config.time { 44 | goFlag = goFlag | log.Ltime 45 | } 46 | if logger.config.microseconds { 47 | goFlag = goFlag | log.Lmicroseconds 48 | } 49 | if logger.config.utc { 50 | goFlag = goFlag | log.LUTC 51 | } 52 | logger.Logger.SetFlags(goFlag) 53 | } 54 | 55 | func (c *luaLoggerOutputConfig) longfileValue(L *lua.LState) string { 56 | if !c.longfile { 57 | return "" 58 | } 59 | return L.Where(1) 60 | } 61 | -------------------------------------------------------------------------------- /tests/suite.lua: -------------------------------------------------------------------------------- 1 | local strings = require 'strings' 2 | 3 | local suite = { 4 | t = nil, 5 | Suite = {}, 6 | } 7 | 8 | function suite.Run(t, testSuite) 9 | local testCount = 0 10 | 11 | -- testSuite must be subclass of suite.Suite, so will have this method 12 | testSuite:SetT(t) 13 | 14 | if testSuite.SetupSuite then 15 | testSuite:SetupSuite() 16 | end 17 | for k, v in pairs(testSuite) do 18 | if strings.has_prefix(k, "Test") then 19 | testCount = testCount + 1 20 | if testSuite.SetupTest then 21 | testSuite:SetupTest() 22 | end 23 | t:Run(k, function(t) 24 | testSuite:SetT(t) 25 | v(testSuite) 26 | end) 27 | testSuite:SetT(t) 28 | if testSuite.TearDownTest then 29 | testSuite:TearDownTest() 30 | end 31 | end 32 | end 33 | if testSuite.TearDownSuite then 34 | testSuite:TearDownSuite() 35 | end 36 | 37 | return testCount 38 | end 39 | 40 | function suite.Suite:new(o) 41 | o = o or {} -- create object if user does not provide one 42 | setmetatable(o, self) 43 | self.__index = self 44 | return o 45 | end 46 | 47 | function suite.Suite:T() 48 | return self.t 49 | end 50 | 51 | function suite.Suite:SetT(t) 52 | self.t = t 53 | end 54 | 55 | function suite.Suite:Run(name, f) 56 | local t = self:T() 57 | self:T():Run(name, function(t) 58 | self:SetT(t) 59 | f(self) 60 | end) 61 | self:SetT(t) 62 | end 63 | 64 | return suite 65 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Dmitry Vasiliev 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /http/server/loader.go: -------------------------------------------------------------------------------- 1 | // Package http_server implements golang package http_server utility functionality for lua. 2 | 3 | package http 4 | 5 | import ( 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // Preload adds http_server to the given Lua state's package.preload table. After it 10 | // has been preloaded, it can be loaded using require: 11 | // 12 | // local http_server = require("http_server") 13 | func Preload(L *lua.LState) { 14 | L.PreloadModule("http_server", Loader) 15 | } 16 | 17 | // Loader is the module loader function. 18 | func Loader(L *lua.LState) int { 19 | 20 | http_server_response_writer_ud := L.NewTypeMetatable(`http_server_response_writer_ud`) 21 | L.SetGlobal(`http_server_response_writer_ud`, http_server_response_writer_ud) 22 | L.SetField(http_server_response_writer_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 23 | "code": HeaderCode, 24 | "header": Header, 25 | "write": Write, 26 | "redirect": Redirect, 27 | "done": Done, 28 | })) 29 | 30 | http_server_ud := L.NewTypeMetatable(`http_server_ud`) 31 | L.SetGlobal(`http_server_ud`, http_server_ud) 32 | L.SetField(http_server_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 33 | "accept": Accept, 34 | "addr": Addr, 35 | "do_handle_file": HandleFile, 36 | "do_handle_string": HandleString, 37 | "do_handle_function": HandleFunction, 38 | })) 39 | 40 | t := L.NewTable() 41 | L.SetFuncs(t, api) 42 | L.Push(t) 43 | return 1 44 | } 45 | 46 | var api = map[string]lua.LGFunction{ 47 | "server": New, 48 | "serve_static": ServeStaticFiles, 49 | } 50 | -------------------------------------------------------------------------------- /humanize/example_test.go: -------------------------------------------------------------------------------- 1 | package humanize 2 | 3 | import ( 4 | "log" 5 | 6 | time "github.com/vadv/gopher-lua-libs/time" 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // humanize.ibytes(number) 11 | func ExampleIBytes() { 12 | state := lua.NewState() 13 | Preload(state) 14 | source := ` 15 | local humanize = require("humanize") 16 | print(humanize.ibytes(1395864371)) 17 | ` 18 | if err := state.DoString(source); err != nil { 19 | log.Fatal(err.Error()) 20 | } 21 | // Output: 22 | // 1.3 GiB 23 | } 24 | 25 | // humanize.parse_bytes(string) 26 | func ExampleParseBytes() { 27 | state := lua.NewState() 28 | Preload(state) 29 | source := ` 30 | local humanize = require("humanize") 31 | print(humanize.parse_bytes("1.3GiB")) 32 | ` 33 | if err := state.DoString(source); err != nil { 34 | log.Fatal(err.Error()) 35 | } 36 | // Output: 37 | // 1395864371 38 | } 39 | 40 | // humanize.time(number) 41 | func ExampleTime() { 42 | state := lua.NewState() 43 | Preload(state) 44 | time.Preload(state) 45 | source := ` 46 | local humanize = require("humanize") 47 | local time = require("time") 48 | print(humanize.time(time.unix() - 61)) 49 | ` 50 | if err := state.DoString(source); err != nil { 51 | log.Fatal(err.Error()) 52 | } 53 | // Output: 54 | // 1 minute ago 55 | } 56 | 57 | // humanize.si(input, unit) 58 | func ExampleSI() { 59 | state := lua.NewState() 60 | Preload(state) 61 | source := ` 62 | local humanize = require("humanize") 63 | print(humanize.si(0.212121, "m")) 64 | ` 65 | if err := state.DoString(source); err != nil { 66 | log.Fatal(err.Error()) 67 | } 68 | // Output: 69 | // 212.121 mm 70 | } 71 | -------------------------------------------------------------------------------- /regexp/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local regexp = require("regexp") 2 | 3 | function Test_compiled_regex_match(t) 4 | local reg, err = regexp.compile("(gopher){2}") 5 | if err then 6 | error(err) 7 | end 8 | assert(not reg:match("gopher"), "must not be matched") 9 | assert(reg:match("gophergopher"), "must be matched") 10 | end 11 | 12 | function Test_find_all_string_submatch(t) 13 | t:Run("1", function(t) 14 | local reg, err = regexp.compile("string: (.*)$") 15 | assert(not err, err) 16 | local result = reg:find_all_string_submatch("my string: 'hello world'") 17 | assert(result[1][2] == "'hello world'", "not found: " .. tostring(result[1][2])) 18 | end) 19 | 20 | t:Run("2", function(t) 21 | local reg, err = regexp.compile("string: '(.*)\\s+(.*)'$") 22 | assert(not err, err) 23 | local result = reg:find_all_string_submatch("my string: 'hello world'") 24 | assert(result[1][2] == "hello", "not found: " .. tostring(result[1][2])) 25 | assert(result[1][3] == "world", "not found: " .. tostring(result[1][3])) 26 | end) 27 | end 28 | 29 | function Test_match(t) 30 | local found, err = regexp.match("(gopher){2}", "gophergopher") 31 | assert(not err, err) 32 | assert(found, "must be matched") 33 | end 34 | 35 | function Test_find_all_string_submatch(t) 36 | local result, err = regexp.find_all_string_submatch("string: '(.*)\\s+(.*)'$", "my string: 'hello world'") 37 | assert(not err, err) 38 | assert(result[1][2] == "hello", "not found: " .. tostring(result[1][2])) 39 | assert(result[1][3] == "world", "not found: " .. tostring(result[1][3])) 40 | end -------------------------------------------------------------------------------- /ioutil/api.go: -------------------------------------------------------------------------------- 1 | // Package ioutil implements golang package ioutil functionality for lua. 2 | package ioutil 3 | 4 | import ( 5 | lio "github.com/vadv/gopher-lua-libs/io" 6 | "io" 7 | "io/ioutil" 8 | 9 | lua "github.com/yuin/gopher-lua" 10 | ) 11 | 12 | // ReadFile lua ioutil.read_file(filepath) reads the file named by filename and returns the contents, returns (string,error) 13 | func ReadFile(L *lua.LState) int { 14 | filename := L.CheckString(1) 15 | data, err := ioutil.ReadFile(filename) 16 | if err == nil { 17 | L.Push(lua.LString(data)) 18 | return 1 19 | } else { 20 | L.Push(lua.LNil) 21 | L.Push(lua.LString(err.Error())) 22 | return 2 23 | } 24 | } 25 | 26 | // WriteFile lua ioutil.write_file(filepath, data) reads the file named by filename and returns the contents, returns (string,error) 27 | func WriteFile(L *lua.LState) int { 28 | filename := L.CheckString(1) 29 | data := L.CheckString(2) 30 | err := ioutil.WriteFile(filename, []byte(data), 0644) 31 | if err != nil { 32 | L.Push(lua.LString(err.Error())) 33 | return 1 34 | } 35 | return 0 36 | } 37 | 38 | func Copy(L *lua.LState) int { 39 | writer := lio.CheckIOWriter(L, 1) 40 | reader := lio.CheckIOReader(L, 2) 41 | L.Pop(L.GetTop()) 42 | if _, err := io.Copy(writer, reader); err != nil { 43 | L.Push(lua.LString(err.Error())) 44 | return 1 45 | } 46 | return 0 47 | } 48 | 49 | func CopyN(L *lua.LState) int { 50 | writer := lio.CheckIOWriter(L, 1) 51 | reader := lio.CheckIOReader(L, 2) 52 | n := L.CheckInt64(3) 53 | L.Pop(L.GetTop()) 54 | if _, err := io.CopyN(writer, reader, n); err != nil { 55 | L.Push(lua.LString(err.Error())) 56 | return 1 57 | } 58 | return 0 59 | } 60 | -------------------------------------------------------------------------------- /zabbix/test/test_api_restream.lua: -------------------------------------------------------------------------------- 1 | local zabbix = require("zabbix") 2 | local inspect = require("inspect") 3 | local http = require("http") 4 | 5 | function Test_zabbix(t) 6 | local zbx = zabbix.new({ url = "http://192.168.184.83:8080", user = "zbgate", passwd = "EeTh9Aiw", debug = true }) 7 | 8 | local err = zbx:login() 9 | assert(not err, err) 10 | 11 | --[[ 12 | local response, err = zbx:request("trigger.get", 13 | { 14 | selectHosts = "extend", selectItems = "extend", selectLastEvent="extend", 15 | output = "extend", sortfield = "priority", 16 | filter = { 17 | sortorder="DESC", value="1", status=0 18 | }, 19 | expandData = "1" 20 | } 21 | ) 22 | if err then error(err) end 23 | 24 | local item_id = 0 25 | if response then 26 | for k, v in pairs(response) do 27 | if v.hosts and v.hosts[1] and v.items and v.items[1] and v.items[1].value_type == "3" then 28 | print(inspect(v)) 29 | item_id = v.items[1].itemid 30 | print(v.hosts[1].host, v.description) 31 | end 32 | end 33 | end 34 | 35 | local err = zbx:save_graph(item_id, "./test/test.png") 36 | if err then error(err) end 37 | --]] 38 | 39 | local response, err = zbx:request("host.get", 40 | { 41 | filter = { 42 | host = { "rt-core-pub01.core.iptv.rt.ru" } 43 | }, 44 | } 45 | ) 46 | assert(not err, err) 47 | assert(response, "must be result") 48 | 49 | local err = zbx:logout() 50 | assert(not err, err) 51 | end 52 | -------------------------------------------------------------------------------- /db/api_mysql.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "database/sql" 5 | "sync" 6 | 7 | _ "github.com/go-sql-driver/mysql" 8 | ) 9 | 10 | type luaMySQL struct { 11 | config *dbConfig 12 | sync.Mutex 13 | db *sql.DB 14 | } 15 | 16 | var ( 17 | sharedMySQL = make(map[string]*luaMySQL, 0) 18 | sharedMySQLLock = &sync.Mutex{} 19 | ) 20 | 21 | func init() { 22 | RegisterDriver(`mysql`, &luaMySQL{}) 23 | } 24 | 25 | func (mysql *luaMySQL) constructor(config *dbConfig) (luaDB, error) { 26 | 27 | sharedMySQLLock.Lock() 28 | defer sharedMySQLLock.Unlock() 29 | 30 | if config.sharedMode { 31 | result, ok := sharedMySQL[config.connString] 32 | if ok { 33 | return result, nil 34 | } 35 | } 36 | 37 | db, err := sql.Open(`mysql`, config.connString) 38 | if err != nil { 39 | return nil, err 40 | } 41 | result := &luaMySQL{config: config} 42 | db.SetMaxIdleConns(config.maxOpenConns) 43 | db.SetMaxOpenConns(config.maxOpenConns) 44 | result.db = db 45 | 46 | if config.sharedMode { 47 | sharedMySQL[config.connString] = result 48 | } 49 | 50 | return result, nil 51 | } 52 | 53 | func (mysql *luaMySQL) getDB() *sql.DB { 54 | mysql.Lock() 55 | defer mysql.Unlock() 56 | return mysql.db 57 | } 58 | 59 | func (mysql *luaMySQL) getTXOptions() *sql.TxOptions { 60 | return &sql.TxOptions{ReadOnly: mysql.config.readOnly} 61 | } 62 | 63 | func (mysql *luaMySQL) closeDB() error { 64 | mysql.Lock() 65 | defer mysql.Unlock() 66 | err := mysql.db.Close() 67 | if err != nil { 68 | return err 69 | } 70 | if mysql.config.sharedMode { 71 | sharedMySQLLock.Lock() 72 | delete(sharedMySQL, mysql.config.connString) 73 | sharedMySQLLock.Unlock() 74 | } 75 | return nil 76 | } 77 | -------------------------------------------------------------------------------- /yaml/encoder.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "github.com/vadv/gopher-lua-libs/io" 5 | lua "github.com/yuin/gopher-lua" 6 | "gopkg.in/yaml.v2" 7 | ) 8 | 9 | const ( 10 | yamlEncoderType = "yaml.Encoder" 11 | ) 12 | 13 | func CheckYAMLEncoder(L *lua.LState, n int) *yaml.Encoder { 14 | ud := L.CheckUserData(n) 15 | if encoder, ok := ud.Value.(*yaml.Encoder); ok { 16 | return encoder 17 | } 18 | L.ArgError(n, yamlEncoderType+" expected") 19 | return nil 20 | } 21 | 22 | func LVYAMLEncoder(L *lua.LState, encoder *yaml.Encoder) lua.LValue { 23 | ud := L.NewUserData() 24 | ud.Value = encoder 25 | L.SetMetatable(ud, L.GetTypeMetatable(yamlEncoderType)) 26 | return ud 27 | } 28 | 29 | func yamlEncoderEncode(L *lua.LState) int { 30 | encoder := CheckYAMLEncoder(L, 1) 31 | arg := L.CheckAny(2) 32 | L.Pop(L.GetTop()) 33 | var value interface{} 34 | err := L.GPCall(func(L *lua.LState) int { 35 | visited := make(map[*lua.LTable]bool) 36 | value = toYAML(L, visited, arg) 37 | return 0 38 | }, lua.LNil) 39 | if err != nil { 40 | L.Push(lua.LString(err.Error())) 41 | return 1 42 | } 43 | if err = encoder.Encode(value); err != nil { 44 | L.Push(lua.LString(err.Error())) 45 | return 1 46 | } 47 | return 0 48 | } 49 | 50 | func registerYAMLEncoder(L *lua.LState) { 51 | mt := L.NewTypeMetatable(yamlEncoderType) 52 | L.SetGlobal(yamlEncoderType, mt) 53 | L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 54 | "encode": yamlEncoderEncode, 55 | })) 56 | } 57 | 58 | func newYAMLEncoder(L *lua.LState) int { 59 | writer := io.CheckIOWriter(L, 1) 60 | L.Pop(L.GetTop()) 61 | encoder := yaml.NewEncoder(writer) 62 | L.Push(LVYAMLEncoder(L, encoder)) 63 | return 1 64 | } 65 | -------------------------------------------------------------------------------- /log/example_test.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "log" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // print(args..) 10 | func Example_Print() { 11 | state := lua.NewState() 12 | Preload(state) 13 | source := ` 14 | local log = require("log") 15 | local info = log.new("STDOUT", "[INFO] ") 16 | info:print("1 ", 2) 17 | ` 18 | if err := state.DoString(source); err != nil { 19 | log.Fatal(err.Error()) 20 | } 21 | // Output: 22 | // [INFO] 1 2 23 | } 24 | 25 | // printf(string, args..) 26 | func Example_Printf() { 27 | state := lua.NewState() 28 | Preload(state) 29 | source := ` 30 | local log = require("log") 31 | local info = log.new("STDOUT", "[INFO] ") 32 | info:printf("%s %d\n", "1", 2) 33 | ` 34 | if err := state.DoString(source); err != nil { 35 | log.Fatal(err.Error()) 36 | } 37 | // Output: 38 | // [INFO] 1 2 39 | } 40 | 41 | // println(string, args..) 42 | func Example_Println() { 43 | state := lua.NewState() 44 | Preload(state) 45 | source := ` 46 | local log = require("log") 47 | local info = log.new("STDOUT", "[INFO] ") 48 | info:println("1", 2) 49 | ` 50 | if err := state.DoString(source); err != nil { 51 | log.Fatal(err.Error()) 52 | } 53 | // Output: 54 | // [INFO] 1 2 55 | } 56 | 57 | // set_flags(config={}) 58 | func Example_SetFlags() { 59 | state := lua.NewState() 60 | Preload(state) 61 | source := ` 62 | local log = require("log") 63 | local logger = log.new() 64 | logger:set_prefix("[prefix] ") 65 | logger:set_flags({longfile=true}) 66 | logger:println("1", 2) 67 | ` 68 | if err := state.DoString(source); err != nil { 69 | log.Fatal(err.Error()) 70 | } 71 | // Output: 72 | // [prefix] :6: 1 2 73 | } 74 | -------------------------------------------------------------------------------- /time/example_test.go: -------------------------------------------------------------------------------- 1 | package time 2 | 3 | import ( 4 | "log" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | // time.sleep(number) 10 | func ExampleSleep() { 11 | state := lua.NewState() 12 | Preload(state) 13 | source := ` 14 | local time = require("time") 15 | local begin = time.unix() 16 | time.sleep(1.2) 17 | local stop = time.unix() 18 | local result = stop - begin 19 | -- round 20 | result = math.floor(result * 10^2 + 0.5) / 10^2 21 | print(result) 22 | ` 23 | if err := state.DoString(source); err != nil { 24 | log.Fatal(err.Error()) 25 | } 26 | // Output: 27 | // 1.2 28 | } 29 | 30 | // time.parse(value, layout) 31 | func ExampleParse() { 32 | state := lua.NewState() 33 | Preload(state) 34 | source := ` 35 | local time = require("time") 36 | local result, err = time.parse("Dec 2 03:33:05 2018", "Jan 2 15:04:05 2006") 37 | if err then error(err) end 38 | print(result) 39 | ` 40 | if err := state.DoString(source); err != nil { 41 | log.Fatal(err.Error()) 42 | } 43 | // Output: 44 | // 1543721585 45 | } 46 | 47 | // time.format(value, layout, timezone) 48 | func ExampleFormat() { 49 | state := lua.NewState() 50 | Preload(state) 51 | source := ` 52 | local time = require("time") 53 | print( time.format(0, "Mon Jan 2 15:04:05 -0700 MST 2006", "UTC") ) 54 | print( time.format(0, "Mon Jan 2 15:04:05 -0700 MST 2006", "Europe/Moscow") ) 55 | print( time.format(1543721585, "Jan 2 15:04:05 2006", "Europe/Moscow") ) 56 | ` 57 | if err := state.DoString(source); err != nil { 58 | log.Fatal(err.Error()) 59 | } 60 | // Output: 61 | // Thu Jan 1 00:00:00 +0000 UTC 1970 62 | // Thu Jan 1 03:00:00 +0300 MSK 1970 63 | // Dec 2 06:33:05 2018 64 | } 65 | -------------------------------------------------------------------------------- /db/example_test.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | // +build sqlite 3 | 4 | package db 5 | 6 | import ( 7 | "log" 8 | 9 | inspect "github.com/vadv/gopher-lua-libs/inspect" 10 | lua "github.com/yuin/gopher-lua" 11 | ) 12 | 13 | // db_ud:query() 14 | func Example_package() { 15 | state := lua.NewState() 16 | Preload(state) 17 | inspect.Preload(state) 18 | source := ` 19 | local db = require("db") 20 | local inspect = require("inspect") 21 | 22 | local sqlite, err = db.open("sqlite3", "file:test.db?cache=shared&mode=memory") 23 | if err then error(err) end 24 | 25 | local result, err = sqlite:query("select \"ok\";") 26 | if err then error(err) end 27 | print(inspect(result.rows)) 28 | 29 | local _, err = sqlite:exec("CREATE TABLE t (id int, name string);") 30 | if err then error(err) end 31 | 32 | local result, err = sqlite:exec("INSERT INTO t VALUES (1, \"chook\");") 33 | if err then error(err) end 34 | print(inspect(result, {newline="", indent=""})) 35 | 36 | local result, err = sqlite:exec("INSERT INTO t VALUES (2, \"gek\");") 37 | if err then error(err) end 38 | print(inspect(result, {newline="", indent=""})) 39 | 40 | local result, err = sqlite:query("select * from t order by id desc;") 41 | if err then error(err) end 42 | 43 | print(inspect(result.columns)) 44 | 45 | for _, row in pairs(result.rows) do 46 | print(inspect(row)) 47 | end 48 | 49 | ` 50 | if err := state.DoString(source); err != nil { 51 | log.Fatal(err.Error()) 52 | } 53 | // Output: 54 | // { { "ok" } } 55 | // {last_insert_id = 1,rows_affected = 1} 56 | // {last_insert_id = 2,rows_affected = 1} 57 | // { "id", "name" } 58 | // { 2, "gek" } 59 | // { 1, "chook" } 60 | } 61 | -------------------------------------------------------------------------------- /argparse/test/test_api.lua: -------------------------------------------------------------------------------- 1 | local inspect = require "inspect" 2 | local argparse = require "argparse" 3 | 4 | local function assert_equal (expected, got) 5 | assert(got == expected, string.format([[expected "%s"; got "%s"]], expected, got)) 6 | end 7 | 8 | local function assert_inspect_equal (expected, got) 9 | assert_equal(inspect(expected), inspect(got)) 10 | end 11 | 12 | function Test_argparse(t) 13 | local parser = argparse("script", "An example.") 14 | parser:argument("input", "Input file.") 15 | parser:option("-o --output", "Output file.", "a.out") 16 | parser:option("-I --include", "Include locations."):count("*") 17 | 18 | local test_input = 'test_input' 19 | local test_output = 'test_input' 20 | local test_include = { "foo", "bar", "baz" } 21 | local test_arg = { 22 | "-o", test_output, 23 | test_input 24 | } 25 | for _, include in ipairs(test_include) do 26 | table.insert(test_arg, '-I') 27 | table.insert(test_arg, include) 28 | end 29 | 30 | local args = parser:parse(test_arg) 31 | print(inspect(args)) 32 | assert_equal(test_input, args.input) 33 | assert_equal(test_output, args.output) 34 | assert_inspect_equal(test_include, args.include) 35 | end 36 | 37 | function Test_argparse_default(t) 38 | local parser = argparse("script", "An example.") 39 | parser:option("-f --foo", "Foo parameter", "default") 40 | local args = parser:parse({}) 41 | assert(args.foo == 'default') 42 | end 43 | 44 | function Test_argparse_help(t) 45 | local parser = argparse("script", "An example.") 46 | parser:option("-f --foo", "Foo parameter", "default") 47 | local help = parser:get_help() 48 | assert(#help > 0, "help is empty") 49 | end -------------------------------------------------------------------------------- /yaml/decoder.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "github.com/vadv/gopher-lua-libs/io" 5 | lua "github.com/yuin/gopher-lua" 6 | "gopkg.in/yaml.v2" 7 | ) 8 | 9 | const ( 10 | yamlDecoderType = "yaml.Decoder" 11 | ) 12 | 13 | func CheckYAMLDecoder(L *lua.LState, n int) *yaml.Decoder { 14 | ud := L.CheckUserData(n) 15 | if decoder, ok := ud.Value.(*yaml.Decoder); ok { 16 | return decoder 17 | } 18 | L.ArgError(n, yamlDecoderType+" expected") 19 | return nil 20 | } 21 | 22 | func LVYAMLDecoder(L *lua.LState, decoder *yaml.Decoder) lua.LValue { 23 | ud := L.NewUserData() 24 | ud.Value = decoder 25 | L.SetMetatable(ud, L.GetTypeMetatable(yamlDecoderType)) 26 | return ud 27 | } 28 | 29 | func yamlDecoderDecode(L *lua.LState) int { 30 | decoder := CheckYAMLDecoder(L, 1) 31 | L.Pop(L.GetTop()) 32 | var value interface{} 33 | if err := decoder.Decode(&value); err != nil { 34 | L.Push(lua.LNil) 35 | L.Push(lua.LString(err.Error())) 36 | return 2 37 | } 38 | L.Push(fromYAML(L, value)) 39 | return 1 40 | } 41 | 42 | func yamlDecoderSetStrict(L *lua.LState) int { 43 | decoder := CheckYAMLDecoder(L, 1) 44 | strict := L.CheckBool(2) 45 | L.Pop(L.GetTop()) 46 | decoder.SetStrict(strict) 47 | return 0 48 | } 49 | 50 | func registerYAMLDecoder(L *lua.LState) { 51 | mt := L.NewTypeMetatable(yamlDecoderType) 52 | L.SetGlobal(yamlDecoderType, mt) 53 | L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 54 | "decode": yamlDecoderDecode, 55 | "set_strict": yamlDecoderSetStrict, 56 | })) 57 | } 58 | 59 | func newYAMLDecoder(L *lua.LState) int { 60 | reader := io.CheckIOReader(L, 1) 61 | L.Pop(L.GetTop()) 62 | decoder := yaml.NewDecoder(reader) 63 | L.Push(LVYAMLDecoder(L, decoder)) 64 | return 1 65 | } 66 | -------------------------------------------------------------------------------- /db/api_sqlite.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | // +build sqlite 3 | 4 | package db 5 | 6 | import ( 7 | "database/sql" 8 | "sync" 9 | 10 | _ "github.com/mattn/go-sqlite3" 11 | ) 12 | 13 | type luaSQLite struct { 14 | config *dbConfig 15 | sync.Mutex 16 | db *sql.DB 17 | } 18 | 19 | func init() { 20 | RegisterDriver(`sqlite3`, &luaSQLite{}) 21 | } 22 | 23 | var ( 24 | sharedSqlite = make(map[string]*luaSQLite, 0) 25 | sharedSqliteLock = &sync.Mutex{} 26 | ) 27 | 28 | func (sqlite *luaSQLite) constructor(config *dbConfig) (luaDB, error) { 29 | 30 | sharedSqliteLock.Lock() 31 | defer sharedSqliteLock.Unlock() 32 | 33 | if config.sharedMode { 34 | result, ok := sharedSqlite[config.connString] 35 | if ok { 36 | return result, nil 37 | } 38 | } 39 | 40 | db, err := sql.Open(`sqlite3`, config.connString) 41 | if err != nil { 42 | return nil, err 43 | } 44 | db.SetMaxIdleConns(config.maxOpenConns) 45 | db.SetMaxOpenConns(config.maxOpenConns) 46 | result := &luaSQLite{config: config} 47 | result.db = db 48 | 49 | if config.sharedMode { 50 | sharedSqlite[config.connString] = result 51 | } 52 | 53 | return result, nil 54 | } 55 | 56 | func (sqlite *luaSQLite) getDB() *sql.DB { 57 | sqlite.Lock() 58 | defer sqlite.Unlock() 59 | return sqlite.db 60 | } 61 | 62 | func (sqlite *luaSQLite) getTXOptions() *sql.TxOptions { 63 | return &sql.TxOptions{ReadOnly: sqlite.config.readOnly} 64 | } 65 | 66 | func (sqlite *luaSQLite) closeDB() error { 67 | sqlite.Lock() 68 | defer sqlite.Unlock() 69 | err := sqlite.db.Close() 70 | if err != nil { 71 | return err 72 | } 73 | if sqlite.config.sharedMode { 74 | sharedSqliteLock.Lock() 75 | delete(sharedSqlite, sqlite.config.connString) 76 | sharedSqliteLock.Unlock() 77 | } 78 | return nil 79 | } 80 | -------------------------------------------------------------------------------- /chef/test/client.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAwAJntEXjF3v9G5Bl0rwFQtervjZrglPgFsn0Ts2LUwft3004 3 | 6uF1RpWv1YXBg5JRP0LsmrPk0jw+JNUVGKqAbk7TcownV3+K4hvM1ve4W5g5hG6b 4 | IEcsTplhhrMs5v8MZlpEphZ1KE39fTL0SYg27D9htMDWPLaculX4DqQDYrHCa+7w 5 | +BA1dduwayn1TsSaBQvV5mNJdpblC2Mg9FOEMl4xYjdNgRixiAa3NyATUCDBM+rj 6 | 9C0ZwJReWSBjOpVJs2vk5O/Y5j9dYytM5lovpRXaQOWb4LSSKwRMYe50Z+8knf4Q 7 | kPx/Ia5rY5zxqmf/evmtnXp0b7GfgiP3tg2trQIDAQABAoIBACLOTM44/Pl82Fzu 8 | yAZzXuDHB7LrWoG9gpme8lJ2oBLlFRGthevOAtxQthcWsAWRuHinQQyqH4icswcq 9 | OTDHd5CHaX0SOu95h0uFjpRJQ3oXFhYTlrs7K6Tz2OH6COG2yiCjrF4PJB2yRYk0 10 | e2P49TvOIYAKlMtcrvx4KQc+Y/63ugTAJhyTmJubJq1cYbPuw+83lnN+xee9046J 11 | QD+/rbPmEGCQ4RvlfezBn08BSilQfVPWAPJyjg/OjPWuwjTHaNC3pumIHy8ynsHf 12 | heEa1Ro6y7mLA0eoI0diSW7IMqdFEuitBx+hWS5jzBhqGb7Cfo6hTePxPnmdCHXx 13 | dwqHOgECgYEA5DlgJ/CsufmiYOj+f7IPsfaRdRjNQZcK1YGXwwW991XpAXtl/ZKc 14 | BpJlMx0MvgGpjwzLgAns4BQWWwa23vjgj8aV0DMlyF7ONwgnn4V9sz1oEpjQF1bb 15 | vVlUteeYc2qtF5eMqZgGJeeSmW38U8/HQNxEtL4/PVh2SV+PN2JrVPECgYEA12C2 16 | M3bjdPOcCoqNDXtAt9Smu5Yi1/sMl84hPlzqa9uDv4hSDUkxz6FXeQ4q7PQ/iwNd 17 | sU8GHmKcFB/+dugHLkk6P2v98E6Do8JQOViSOWiLAEeSkcFIeibmN8/6mx4ww87D 18 | HqP2rQOyx969A7fi0/jexAHmhPMgZhpv7LeodH0CgYA0ZGuLn7e3VfSN9M7/95uc 19 | yjLoQ9JS/V6yVvbFAZtznVhJS8/FH5QL+i2bR072i6EmQtSwxxaG9nWPXgI7O70p 20 | pHgd/K/uyLzka03VVCrgK/epVUVoJjt5w3kr7UfVLycfZF4ZTNoUd43zBQnJH8jp 21 | PefT6lzQM2+sNnDFUSW8sQKBgH0v5JfDWfBnjOJ/p/8XDgYMH6HXYYdij+5IzP/f 22 | qA5rOIgCp5a7Xa2O3TYq6v5x9eFKYpImGatdq9Tyx8i7kzjvLWEh1ydvq4pq7pB2 23 | j/+4aVsPPv1jeEowBA6a39J72OJncviDW2UzSh5stDbOEpUdCfaqGCBc5Q8T/Mx9 24 | 7/dNAoGBAJI6H1bSaxxI65d8XvwfK6zwAVzFAiBbIwK9qS8zT4t0r9R1TN/CnGl9 25 | 7p6pKNpYz1QtToFluEzSyKargQ+7f2VLBhr+S8eN4Z8t3yhF38c3feIGOQ6pldWw 26 | USu0swoyDzxJP764VZcH8cTNDssV/z4w/ZneKgL2ZkSz/IXhp0U1 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chef/test/test_api_restream.lua: -------------------------------------------------------------------------------- 1 | local http = require("http") 2 | local chef = require("chef") 3 | local inspect = require("inspect") 4 | 5 | local node = "chef.itv.restr.im" 6 | 7 | local http_client = http.client({ insecure_ssl = true, timeout = 20 }) 8 | local client = chef.client( 9 | "lualibs", 10 | "./test/client.pem", 11 | "https://chef.itv.restr.im/organizations/restream/", 12 | http_client 13 | ) 14 | 15 | function TestNodes(t) 16 | -- nodes 17 | local result, err = client:request("GET", "nodes") 18 | assert(not err, err) 19 | local found = false 20 | for k, v in pairs(result) do 21 | if k == node then 22 | found = true 23 | end 24 | end 25 | assert(found, "nodes don't contain " .. node) 26 | end 27 | 28 | function TestNodes(t) 29 | -- node 30 | local result, err = client:request("GET", "nodes/" .. node) 31 | assert(not err, err) 32 | t:Log(result.default) 33 | t:Log(result.automatic) 34 | t:Log(result.normal) 35 | t:Log(result.override) 36 | assert(result.name == node, "get node: " .. result.name) 37 | end 38 | 39 | function TestSearch(t) 40 | t:Run("1", function(t) 41 | local result, err = client:search("node", "fqdn:" .. node) 42 | assert(not err, err) 43 | assert(result.rows[1].name == node, "search node 1: " .. result.rows[1].name) 44 | end) 45 | 46 | t:Run("2", function(t) 47 | -- search 2 48 | local result, err = client:search("node", "fqdn:" .. node, { fqdn_name = { "name" } }) 49 | assert(not err, err) 50 | t:Log(inspect(result.rows[1].data)) 51 | assert(result.rows[1].data.fqdn_name == node, "search node 2: " .. tostring(result.rows[1].data.fqdn_name)) 52 | end) 53 | end 54 | -------------------------------------------------------------------------------- /tac/api.go: -------------------------------------------------------------------------------- 1 | // Package tac implements file scanner (from end to up) functionality for lua. 2 | package tac 3 | 4 | import ( 5 | "os" 6 | 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | type luaTac struct { 11 | filename string 12 | fd *os.File 13 | scanner *tacScanner 14 | } 15 | 16 | func checkTac(L *lua.LState, n int) *luaTac { 17 | ud := L.CheckUserData(1) 18 | if v, ok := ud.Value.(*luaTac); ok { 19 | return v 20 | } 21 | L.ArgError(1, "tac expected") 22 | return nil 23 | } 24 | 25 | func (t *luaTac) open() error { 26 | fd, err := os.Open(t.filename) 27 | if err != nil { 28 | return err 29 | } 30 | t.fd = fd 31 | t.scanner = newTacScanner(fd) 32 | return nil 33 | } 34 | 35 | // Open lua tac.open(filename) open filename for tac scan returns (tac_ud, err) 36 | func Open(L *lua.LState) int { 37 | t := &luaTac{filename: L.CheckString(1)} 38 | if err := t.open(); err != nil { 39 | L.Push(lua.LNil) 40 | L.Push(lua.LString(err.Error())) 41 | return 2 42 | } 43 | ud := L.NewUserData() 44 | ud.Value = t 45 | L.SetMetatable(ud, L.GetTypeMetatable("tac_ud")) 46 | L.Push(ud) 47 | return 1 48 | } 49 | 50 | // Line lua tac_ud:line() return next upper line: string or nil 51 | func Line(L *lua.LState) int { 52 | t := checkTac(L, 1) 53 | if t.scanner == nil { 54 | L.RaiseError("tac not initialized") 55 | return 0 56 | } 57 | if t.scanner.scan() { 58 | text := t.scanner.text() 59 | L.Push(lua.LString(text)) 60 | return 1 61 | } 62 | L.Push(lua.LNil) 63 | return 1 64 | } 65 | 66 | // Close lua tac_ud:close() close current file for tac 67 | func Close(L *lua.LState) int { 68 | t := checkTac(L, 1) 69 | if t.fd == nil { 70 | L.RaiseError("tac not initialized") 71 | return 0 72 | } 73 | t.fd.Close() 74 | t = nil 75 | return 0 76 | } 77 | -------------------------------------------------------------------------------- /tests/data/zabbix3/ssl/nginx.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAoTu7XbP49EDaZP5LJb8b6SJUh0pyzzaPxfK1CSpF8fZWv9aG 3 | zRejdQLZNKJUFTn/qAnHWPLGcv1dT6R+wqHm9GMWIJ37fgmvJuqmwbf9sl6v+D/M 4 | PkJ1RxM0uU7evBgXpaVFwOC23aHjd7mAEi3ZWPefnKAg2aGUr56rY5JNh0zjZz8g 5 | 5lJ2gPG0J2tllbneXFwaQhB0ZjGJyzsIb4c8Q41xF9SxZfpL8dS6HxeSuBYUhhqh 6 | qSCRFnkPxDqMKTSH32SAw8b1tgcMvx03iQcSPeJx+VKmbZnjGx8wT0J5txyrRp2m 7 | ceFC82kpspjedMeFJZ6hTax/qKjyczf2Y5VPDQIDAQABAoIBAEb1jemYaom8/SET 8 | lakgKb16AW+lgU/W+IGq5qgI9c2el+FIHf2nWKYHweZbRtwssWqYGyb3egVjoqyJ 9 | fcxVCtslvLhQLz3yLybWgNujCUF2UMXV9iK0hv7n4f1oS7jGdanOShuwCmsSc5Te 10 | jBH0IcL5AEMjajG93j1IfK+O1RYlOtuVFF7wmLFryHsBaA7aSYktNGGrlguxcv52 11 | y2F9QtON93Bcsowp4LGEYkYYOX2OsWmTGXOMh1kyZ3Shy9oi/8yEhZ/qAQKBXh5O 12 | YLOMWRH8PmuiAYnVF+Tnt+QZ2/s9HjgsDHjoDbgjkykEVrvBcQGgp5S7cVK4JJjd 13 | dB+KTRUCgYEAzeGIqWvSIyvOw+Z2BJjnFjnROgKCGczYlCXjct+KfL827wmbRggF 14 | FWBUZ+xI4a16wX3rkp9BC3mxOtlx6jh+WCChDi1DGH2hSioWpKKE749toLa0LxT9 15 | ve9NuiOIXmGeXRmqjP+03o6sCfRlKnSPClCGJwh6UlIIVCK58SJgXycCgYEAyHvD 16 | g6ojGV2ZgAg1bMWqxpzy3epC8Ky395ckmpw0DuuHJYYtZMqZy50J9RtGDgiOCawl 17 | 1jO9XEo2dfKOeaCy+V5RZPgGsRPF9SQB/nJ6CRA8hkeqW6fUCZp7q+fQFQXDPQZ4 18 | qcOlp4k3C8R9iGuvbucm0+JZCwPOAW/9z+K0QKsCgYAN83+IQ4cs3PYY7lAHBbl7 19 | FxXngW4Bg5EVkO+1xBIlW+vEDPmZqEd36Fwv4qIZsODFpdvFxsbomSl6XGvMvGFL 20 | ZYKkbErEqRa56No5881gUm7SWi8hlaGQMlwpBeliw+iwVGHrRhSilDZyQj5svxNG 21 | VqiQkpF/bJGl6eiBv5uaNwKBgFoWSxe59wWp6pT+m0siU4fl9LhFUQknA4+tChSz 22 | hi0CJvt0nKdC5vL4wQWz2LnrnC+6fFIRc9CpxGkhsmXzERk/CaIuVYtykCyEnqTA 23 | uheihR/tyh5ffsdF9LaddwJLUZz1cHkQYjqzTNnr1GDdyroyAl+JwWtSrVo2Ab5N 24 | Z6P7AoGBALcSMMfMknl/hwNA2mntRCMK9eN6my/pgns3BZmZ537AKOm1xCSNZUnd 25 | 07UG0czBygEM5/VEU7gupYoONwi1q79pGYOc2hmXQ73v1OLUUJSt8X8RCQE9EePs 26 | la48XF7MMhCwjJCNt5El0oqdU4p3WiVZUW/lbkl59SKQ5SKT3LPV 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /telegram/loader.go: -------------------------------------------------------------------------------- 1 | package telegram 2 | 3 | import ( 4 | lua "github.com/yuin/gopher-lua" 5 | ) 6 | 7 | // Preload adds telegram to the given Lua state's package.preload table. After it 8 | // has been preloaded, it can be loaded using require: 9 | // 10 | // local telegram = require("telegram") 11 | func Preload(L *lua.LState) { 12 | L.PreloadModule("telegram", Loader) 13 | } 14 | 15 | // Loader is the module loader function. 16 | func Loader(L *lua.LState) int { 17 | 18 | telegram_bot_ud := L.NewTypeMetatable(`telegram_bot_ud`) 19 | L.SetGlobal(`telegram_bot_ud`, telegram_bot_ud) 20 | L.SetField(telegram_bot_ud, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{ 21 | "getUpdates": GetUpdates, // https://core.telegram.org/bots/api#getupdates 22 | "getOffset": GetOffset, // max offset value in updates 23 | "sendMessage": SendMessage, // https://core.telegram.org/bots/api#sendmessage 24 | "deleteMessage": DeleteMessage, // https://core.telegram.org/bots/api#deletemessage 25 | "forwardMessage": ForwardMessage, // https://core.telegram.org/bots/api#forwardmessage 26 | "sendPhoto": SendPhoto, // https://core.telegram.org/bots/api#sendphoto 27 | "editMessageText": EditMessageText, // https://core.telegram.org/bots/api#editMessageText 28 | "editMessageCaption": EditMessageCaption, // https://core.telegram.org/bots/api#editMessageCaption 29 | "editMessageReplyMarkup": EditMessageReplyMarkup, // https://core.telegram.org/bots/api#editMessageReplyMarkup 30 | })) 31 | 32 | t := L.NewTable() 33 | L.SetFuncs(t, api) 34 | L.Push(t) 35 | return 1 36 | } 37 | 38 | var api = map[string]lua.LGFunction{ 39 | "bot": NewBot, 40 | } 41 | -------------------------------------------------------------------------------- /regexp/README.md: -------------------------------------------------------------------------------- 1 | # regexp [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/regexp?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/regexp) 2 | 3 | ## Usage 4 | 5 | ```lua 6 | local regexp = require("regexp") 7 | local inspect = require("inspect") 8 | 9 | -- regexp.match(regexp, data) 10 | local result, err = regexp.match("hello", "hello world") 11 | if err then error(err) end 12 | if not(result==true) then error("regexp.match()") end 13 | 14 | -- regexp.find_all_string_submatch(regexp, data) 15 | local result, err = regexp.find_all_string_submatch("string: '(.*)\\s+(.*)'$", "my string: 'hello world'") 16 | if err then error(err) end 17 | if not(result[1][2] == "hello") then error("not found: "..tostring(result[1][2])) end 18 | if not(result[1][3] == "world") then error("not found: "..tostring(result[1][3])) end 19 | 20 | -- regexp:match() 21 | local reg, err = regexp.compile("hello") 22 | if err then error(err) end 23 | local result = reg:match("string: 'hello world'") 24 | if not(result==true) then error("regexp:match()") end 25 | 26 | -- regexp:find_all_string_submatch() 27 | local reg, err = regexp.compile("string: '(.*)\\s+(.*)'$") 28 | if err then error(err) end 29 | local result = reg:find_all_string_submatch("string: 'hello world'") 30 | local result = inspect(result, {newline="", indent=""}) 31 | if not(result == [[{ { "string: 'hello world'", "hello", "world" } }]]) then error("regexp:find_all_string_submatch()") end 32 | 33 | -- regexp.find_all_string_submatch(regexp, data) 34 | local result, err = regexp.find_all_string_submatch("string: '(.*)\\s+(.*)'$", "my string: 'hello world'") 35 | if err then error(err) end 36 | if not(result[1][2] == "hello") then error("not found: "..tostring(result[1][2])) end 37 | if not(result[1][3] == "world") then error("not found: "..tostring(result[1][3])) end 38 | ``` 39 | -------------------------------------------------------------------------------- /goos/api.go: -------------------------------------------------------------------------------- 1 | // Package goos implements golang package os functionality for lua. 2 | package goos 3 | 4 | import ( 5 | "os" 6 | "strings" 7 | 8 | lua "github.com/yuin/gopher-lua" 9 | ) 10 | 11 | // Stat lua goos.stat(filename) returns (table, err) 12 | func Stat(L *lua.LState) int { 13 | filename := L.CheckString(1) 14 | stat, err := os.Stat(filename) 15 | if err != nil { 16 | L.Push(lua.LNil) 17 | L.Push(lua.LString(err.Error())) 18 | return 2 19 | } 20 | result := L.NewTable() 21 | result.RawSetString(`is_dir`, lua.LBool(stat.IsDir())) 22 | result.RawSetString(`size`, lua.LNumber(stat.Size())) 23 | result.RawSetString(`mod_time`, lua.LNumber(stat.ModTime().Unix())) 24 | result.RawSetString(`mode`, lua.LString(stat.Mode().String())) 25 | L.Push(result) 26 | return 1 27 | } 28 | 29 | // Hostname lua goos.hostname() returns (string, error) 30 | func Hostname(L *lua.LState) int { 31 | hostname, err := os.Hostname() 32 | if err != nil { 33 | L.Push(lua.LNil) 34 | L.Push(lua.LString(err.Error())) 35 | return 2 36 | } 37 | L.Push(lua.LString(hostname)) 38 | return 1 39 | } 40 | 41 | // Getpagesize lua goos.pagesize() return number 42 | func Getpagesize(L *lua.LState) int { 43 | L.Push(lua.LNumber(os.Getpagesize())) 44 | return 1 45 | } 46 | 47 | // MkdirAll lua goos.mkdir_all() return err 48 | func MkdirAll(L *lua.LState) int { 49 | err := os.MkdirAll(L.CheckString(1), 0755) 50 | if err != nil { 51 | L.Push(lua.LString(err.Error())) 52 | return 1 53 | } 54 | return 0 55 | } 56 | 57 | // Environ lua goos.environ() returns table 58 | func Environ(L *lua.LState) int { 59 | envVars := os.Environ() 60 | result := L.NewTable() 61 | for _, env := range envVars { 62 | parts := strings.SplitN(env, "=", 2) 63 | result.RawSetString(parts[0], lua.LString(parts[1])) 64 | } 65 | L.Push(result) 66 | return 1 67 | } 68 | -------------------------------------------------------------------------------- /http/server/request.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | 7 | lua "github.com/yuin/gopher-lua" 8 | ) 9 | 10 | // NewRequest return lua table with http.Request representation 11 | func NewRequest(L *lua.LState, req *http.Request) *lua.LTable { 12 | luaRequest := L.NewTable() 13 | bodyReader := L.NewFunction(func(L *lua.LState) int { 14 | data, err := ioutil.ReadAll(req.Body) 15 | if err != nil { 16 | L.Push(lua.LNil) 17 | L.Push(lua.LString(err.Error())) 18 | return 2 19 | } 20 | L.Push(lua.LString(string(data))) 21 | return 1 22 | }) 23 | luaRequest.RawSetString(`body`, bodyReader) 24 | luaRequest.RawSetString(`host`, lua.LString(req.Host)) 25 | luaRequest.RawSetString(`method`, lua.LString(req.Method)) 26 | luaRequest.RawSetString(`referer`, lua.LString(req.Referer())) 27 | luaRequest.RawSetString(`proto`, lua.LString(req.Proto)) 28 | luaRequest.RawSetString(`user_agent`, lua.LString(req.UserAgent())) 29 | if req.URL != nil && len(req.URL.Query()) > 0 { 30 | query := L.NewTable() 31 | for k, v := range req.URL.Query() { 32 | if len(v) > 0 { 33 | query.RawSetString(k, lua.LString(v[0])) 34 | } 35 | } 36 | luaRequest.RawSetString(`query`, query) 37 | } 38 | if len(req.Header) > 0 { 39 | headers := L.NewTable() 40 | for k, v := range req.Header { 41 | if len(v) > 0 { 42 | headers.RawSetString(k, lua.LString(v[0])) 43 | } 44 | } 45 | luaRequest.RawSetString(`headers`, headers) 46 | } 47 | luaRequest.RawSetString(`path`, lua.LString(req.URL.Path)) 48 | luaRequest.RawSetString(`raw_path`, lua.LString(req.URL.RawPath)) 49 | luaRequest.RawSetString(`raw_query`, lua.LString(req.URL.RawQuery)) 50 | luaRequest.RawSetString(`request_uri`, lua.LString(req.RequestURI)) 51 | luaRequest.RawSetString(`remote_addr`, lua.LString(req.RemoteAddr)) 52 | return luaRequest 53 | } 54 | -------------------------------------------------------------------------------- /bit/api.go: -------------------------------------------------------------------------------- 1 | // Package bit implements Go bitwise operations functionality for Lua. 2 | package bit 3 | 4 | import ( 5 | "fmt" 6 | "math" 7 | 8 | lua "github.com/yuin/gopher-lua" 9 | ) 10 | 11 | type op uint 12 | 13 | const ( 14 | and op = iota 15 | or 16 | not 17 | xor 18 | ls 19 | rs 20 | ) 21 | 22 | // Bitwise returns a Lua function used for bitwise operations. 23 | func Bitwise(kind op) lua.LGFunction { 24 | return func(l *lua.LState) int { 25 | if kind > rs { 26 | l.RaiseError("unsupported operation type") 27 | return 0 28 | } 29 | val1, val2, err := prepareParams(l) 30 | if err != nil { 31 | l.Push(lua.LNil) 32 | l.Push(lua.LString(err.Error())) 33 | return 2 34 | } 35 | var ret uint32 36 | switch kind { 37 | case and: 38 | ret = val1 & val2 39 | case or: 40 | ret = val1 | val2 41 | case xor: 42 | ret = val1 ^ val2 43 | case ls: 44 | ret = val1 << val2 45 | case rs: 46 | ret = val1 >> val2 47 | } 48 | l.Push(lua.LNumber(ret)) 49 | return 1 50 | } 51 | } 52 | 53 | // Not implements bitwise not. 54 | func Not(l *lua.LState) int { 55 | val, err := intToU32(l.CheckInt(1)) 56 | if err != nil { 57 | l.Push(lua.LNil) 58 | l.Push(lua.LString(err.Error())) 59 | return 2 60 | } 61 | l.Push(lua.LNumber(^val)) 62 | return 1 63 | } 64 | 65 | func prepareParams(l *lua.LState) (val1, val2 uint32, err error) { 66 | val1, err = intToU32(l.CheckInt(1)) 67 | if err != nil { 68 | return 0, 0, err 69 | } 70 | val2, err = intToU32(l.CheckInt(2)) 71 | if err != nil { 72 | return 0, 0, err 73 | } 74 | return 75 | } 76 | 77 | func intToU32(i int) (uint32, error) { 78 | if i < 0 { 79 | return 0, fmt.Errorf("cannot convert negative int %d to uint32", i) 80 | } 81 | if i > math.MaxUint32 { 82 | return 0, fmt.Errorf("int %d overflows uint32", i) 83 | } 84 | return uint32(i), nil 85 | } 86 | --------------------------------------------------------------------------------