mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
Lua: Add support for more advanced syntax (#2908)
* Add lua/rocksepc support for variables substitution * Lua: Skip expressions in rockspec packages * Lua: Add support for concatenation of string and variables * Lua: Skip expressions in local * Lua: Skip build sections in Rockspec files * Lua: skip function blocks in Rockspec * Lua: Add support for multi variable per line --------- Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
This commit is contained in:
parent
5cf8cc9bc3
commit
eeb4193d4a
@ -76,6 +76,27 @@ func TestParseRockspec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Fixture: "test-fixtures/rockspec/luasyslog-2.0.1-1.rockspec",
|
||||||
|
ExpectedPkg: pkg.Package{
|
||||||
|
Name: "luasyslog",
|
||||||
|
Version: "2.0.1-1",
|
||||||
|
PURL: "pkg:luarocks/luasyslog@2.0.1-1",
|
||||||
|
Type: pkg.LuaRocksPkg,
|
||||||
|
Language: pkg.Lua,
|
||||||
|
Licenses: pkg.NewLicenseSet(
|
||||||
|
pkg.NewLicenseFromLocations("MIT/X11", file.NewLocation("test-fixtures/rockspec/luasyslog-2.0.1-1.rockspec")),
|
||||||
|
),
|
||||||
|
Metadata: pkg.LuaRocksPackage{
|
||||||
|
Name: "luasyslog",
|
||||||
|
Version: "2.0.1-1",
|
||||||
|
License: "MIT/X11",
|
||||||
|
Homepage: "https://github.com/lunarmodules/luasyslog",
|
||||||
|
Description: "Syslog logging for Lua",
|
||||||
|
URL: "git://github.com/lunarmodules/luasyslog.git",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|||||||
@ -45,7 +45,8 @@ func parseRockspecData(reader io.Reader) (rockspec, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
blocks, err := parseRockspecBlock(data, &i)
|
locals := make(map[string]string)
|
||||||
|
blocks, err := parseRockspecBlock(data, &i, locals)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return noReturn, err
|
return noReturn, err
|
||||||
@ -56,9 +57,9 @@ func parseRockspecData(reader io.Reader) (rockspec, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseRockspecBlock(data []byte, i *int) ([]rockspecNode, error) {
|
func parseRockspecBlock(data []byte, i *int, locals map[string]string) ([]rockspecNode, error) {
|
||||||
var out []rockspecNode
|
var out []rockspecNode
|
||||||
var iterator func(data []byte, i *int) (*rockspecNode, error)
|
var iterator func(data []byte, i *int, locals map[string]string) (*rockspecNode, error)
|
||||||
|
|
||||||
parsing.SkipWhitespace(data, i)
|
parsing.SkipWhitespace(data, i)
|
||||||
|
|
||||||
@ -67,6 +68,14 @@ func parseRockspecBlock(data []byte, i *int) ([]rockspecNode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c := data[*i]
|
c := data[*i]
|
||||||
|
|
||||||
|
// Block starting with a comment
|
||||||
|
if c == '-' {
|
||||||
|
parseComment(data, i)
|
||||||
|
parsing.SkipWhitespace(data, i)
|
||||||
|
c = data[*i]
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case c == '"' || c == '\'':
|
case c == '"' || c == '\'':
|
||||||
iterator = parseRockspecListItem
|
iterator = parseRockspecListItem
|
||||||
@ -77,7 +86,7 @@ func parseRockspecBlock(data []byte, i *int) ([]rockspecNode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for *i < len(data) {
|
for *i < len(data) {
|
||||||
item, err := iterator(data, i)
|
item, err := iterator(data, i, locals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%w\n%s", err, parsing.PrintError(data, *i))
|
return nil, fmt.Errorf("%w\n%s", err, parsing.PrintError(data, *i))
|
||||||
}
|
}
|
||||||
@ -99,7 +108,7 @@ func parseRockspecBlock(data []byte, i *int) ([]rockspecNode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//nolint:funlen, gocognit
|
//nolint:funlen, gocognit
|
||||||
func parseRockspecNode(data []byte, i *int) (*rockspecNode, error) {
|
func parseRockspecNode(data []byte, i *int, locals map[string]string) (*rockspecNode, error) {
|
||||||
parsing.SkipWhitespace(data, i)
|
parsing.SkipWhitespace(data, i)
|
||||||
|
|
||||||
if *i >= len(data) {
|
if *i >= len(data) {
|
||||||
@ -136,7 +145,7 @@ func parseRockspecNode(data []byte, i *int) (*rockspecNode, error) {
|
|||||||
return nil, fmt.Errorf("invalid literal character: %s", string(c))
|
return nil, fmt.Errorf("invalid literal character: %s", string(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := parseRockspecLiteral(data, i)
|
key, err := parseRockspecLiteral(data, i, locals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -147,6 +156,16 @@ func parseRockspecNode(data []byte, i *int) (*rockspecNode, error) {
|
|||||||
return nil, fmt.Errorf("unexpected end of node at %d", *i)
|
return nil, fmt.Errorf("unexpected end of node at %d", *i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if key == "local" {
|
||||||
|
err := parseLocal(data, i, locals)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &rockspecNode{
|
||||||
|
key: ",",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
c = data[*i]
|
c = data[*i]
|
||||||
if c != '=' {
|
if c != '=' {
|
||||||
return nil, fmt.Errorf("unexpected character: %s", string(c))
|
return nil, fmt.Errorf("unexpected character: %s", string(c))
|
||||||
@ -159,6 +178,14 @@ func parseRockspecNode(data []byte, i *int) (*rockspecNode, error) {
|
|||||||
return nil, fmt.Errorf("unexpected end of node at %d", *i)
|
return nil, fmt.Errorf("unexpected end of node at %d", *i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if key == "build" {
|
||||||
|
skipBuildNode(data, i)
|
||||||
|
|
||||||
|
return &rockspecNode{
|
||||||
|
key: ",",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
c = data[*i]
|
c = data[*i]
|
||||||
|
|
||||||
switch c {
|
switch c {
|
||||||
@ -180,7 +207,7 @@ func parseRockspecNode(data []byte, i *int) (*rockspecNode, error) {
|
|||||||
|
|
||||||
parsing.SkipWhitespace(data, i)
|
parsing.SkipWhitespace(data, i)
|
||||||
|
|
||||||
obj, err := parseRockspecBlock(data, i)
|
obj, err := parseRockspecBlock(data, i, locals)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -190,16 +217,10 @@ func parseRockspecNode(data []byte, i *int) (*rockspecNode, error) {
|
|||||||
return &rockspecNode{
|
return &rockspecNode{
|
||||||
key, value,
|
key, value,
|
||||||
}, nil
|
}, nil
|
||||||
case '"', '\'':
|
case '(':
|
||||||
str, err := parseRockspecString(data, i)
|
skipExpression(data, i)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
value := str.value
|
|
||||||
|
|
||||||
return &rockspecNode{
|
return &rockspecNode{
|
||||||
key, value,
|
key: ",",
|
||||||
}, nil
|
}, nil
|
||||||
case '[':
|
case '[':
|
||||||
offset := *i + 1
|
offset := *i + 1
|
||||||
@ -214,7 +235,7 @@ func parseRockspecNode(data []byte, i *int) (*rockspecNode, error) {
|
|||||||
|
|
||||||
*i++
|
*i++
|
||||||
|
|
||||||
str, err := parseRockspecString(data, i)
|
str, err := parseRockspecString(data, i, locals)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -234,10 +255,18 @@ func parseRockspecNode(data []byte, i *int) (*rockspecNode, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
value, err := parseRockspecValue(data, i, locals, "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &rockspecNode{
|
||||||
|
key, value,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseRockspecListItem(data []byte, i *int) (*rockspecNode, error) {
|
func parseRockspecListItem(data []byte, i *int, locals map[string]string) (*rockspecNode, error) {
|
||||||
parsing.SkipWhitespace(data, i)
|
parsing.SkipWhitespace(data, i)
|
||||||
|
|
||||||
if *i >= len(data) {
|
if *i >= len(data) {
|
||||||
@ -269,14 +298,70 @@ func parseRockspecListItem(data []byte, i *int) (*rockspecNode, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
str, err := parseRockspecString(data, i)
|
str, err := parseRockspecString(data, i, locals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return str, nil
|
return str, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseRockspecLiteral(data []byte, i *int) (string, error) {
|
func parseRockspecValue(data []byte, i *int, locals map[string]string, initialValue string) (string, error) {
|
||||||
|
c := data[*i]
|
||||||
|
|
||||||
|
var value string
|
||||||
|
|
||||||
|
switch c {
|
||||||
|
case '"', '\'':
|
||||||
|
str, err := parseRockspecString(data, i, locals)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
value = str.value.(string)
|
||||||
|
default:
|
||||||
|
local, err := parseRockspecLiteral(data, i, locals)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
l, ok := locals[local]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("unknown local: %s", local)
|
||||||
|
}
|
||||||
|
|
||||||
|
value = l
|
||||||
|
}
|
||||||
|
|
||||||
|
value = fmt.Sprintf("%s%s", initialValue, value)
|
||||||
|
|
||||||
|
skipWhitespaceNoNewLine(data, i)
|
||||||
|
|
||||||
|
if len(data) > *i+2 {
|
||||||
|
if data[*i] == '.' && data[*i+1] == '.' {
|
||||||
|
*i += 2
|
||||||
|
|
||||||
|
skipWhitespaceNoNewLine(data, i)
|
||||||
|
|
||||||
|
if *i >= len(data) {
|
||||||
|
return "", fmt.Errorf("unexpected end of expression at %d", *i)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := parseRockspecValue(data, i, locals, value)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
value = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseRockspecLiteral(data []byte, i *int, locals map[string]string) (string, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
out:
|
out:
|
||||||
for *i < len(data) {
|
for *i < len(data) {
|
||||||
@ -284,7 +369,7 @@ out:
|
|||||||
switch {
|
switch {
|
||||||
case c == '[':
|
case c == '[':
|
||||||
*i++
|
*i++
|
||||||
nested, err := parseRockspecString(data, i)
|
nested, err := parseRockspecString(data, i, locals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -303,7 +388,7 @@ out:
|
|||||||
return buf.String(), nil
|
return buf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseRockspecString(data []byte, i *int) (*rockspecNode, error) {
|
func parseRockspecString(data []byte, i *int, _ map[string]string) (*rockspecNode, error) {
|
||||||
delim := data[*i]
|
delim := data[*i]
|
||||||
var endDelim byte
|
var endDelim byte
|
||||||
switch delim {
|
switch delim {
|
||||||
@ -344,9 +429,171 @@ func parseComment(data []byte, i *int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:funlen
|
||||||
|
func parseLocal(data []byte, i *int, locals map[string]string) error {
|
||||||
|
keys := []string{}
|
||||||
|
values := []string{}
|
||||||
|
|
||||||
|
keys:
|
||||||
|
for {
|
||||||
|
parsing.SkipWhitespace(data, i)
|
||||||
|
|
||||||
|
key, err := parseRockspecLiteral(data, i, locals)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if key == "function" {
|
||||||
|
err := skipFunction(data, i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keys = append(keys, key)
|
||||||
|
|
||||||
|
parsing.SkipWhitespace(data, i)
|
||||||
|
|
||||||
|
c := data[*i]
|
||||||
|
|
||||||
|
switch c {
|
||||||
|
case ',':
|
||||||
|
*i++
|
||||||
|
continue
|
||||||
|
case '=':
|
||||||
|
*i++
|
||||||
|
break keys
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unexpected character: %s", string(c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
values:
|
||||||
|
for {
|
||||||
|
skipWhitespaceNoNewLine(data, i)
|
||||||
|
|
||||||
|
c := data[*i]
|
||||||
|
|
||||||
|
switch c {
|
||||||
|
case '"', '\'':
|
||||||
|
value, err := parseRockspecString(data, i, locals)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
values = append(values, value.value.(string))
|
||||||
|
default:
|
||||||
|
ref, err := parseRockspecLiteral(data, i, locals)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if it's an expression
|
||||||
|
skipWhitespaceNoNewLine(data, i)
|
||||||
|
c := data[*i]
|
||||||
|
|
||||||
|
var value string
|
||||||
|
|
||||||
|
if c != '\n' && c != '\r' {
|
||||||
|
skipExpression(data, i)
|
||||||
|
value = ""
|
||||||
|
} else {
|
||||||
|
value = locals[ref]
|
||||||
|
}
|
||||||
|
|
||||||
|
values = append(values, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
skipWhitespaceNoNewLine(data, i)
|
||||||
|
|
||||||
|
c = data[*i]
|
||||||
|
|
||||||
|
switch c {
|
||||||
|
case ',':
|
||||||
|
*i++
|
||||||
|
continue
|
||||||
|
case '\n', '\r':
|
||||||
|
parsing.SkipWhitespace(data, i)
|
||||||
|
break values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(keys) != len(values) {
|
||||||
|
return fmt.Errorf("expected %d values got %d", len(keys), len(values))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(keys); i++ {
|
||||||
|
locals[keys[i]] = values[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipBuildNode(data []byte, i *int) {
|
||||||
|
bracesCount := 0
|
||||||
|
|
||||||
|
for *i < len(data) {
|
||||||
|
c := data[*i]
|
||||||
|
|
||||||
|
switch c {
|
||||||
|
case '{':
|
||||||
|
bracesCount++
|
||||||
|
case '}':
|
||||||
|
bracesCount--
|
||||||
|
}
|
||||||
|
|
||||||
|
if bracesCount == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
*i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipFunction(data []byte, i *int) error {
|
||||||
|
blocks := 1
|
||||||
|
|
||||||
|
for *i < len(data)-5 {
|
||||||
|
if parsing.IsWhitespace(data[*i]) {
|
||||||
|
switch {
|
||||||
|
case string(data[*i+1:*i+3]) == "if" && parsing.IsWhitespace(data[*i+3]):
|
||||||
|
blocks++
|
||||||
|
*i += 3
|
||||||
|
case string(data[*i+1:*i+4]) == "end" && parsing.IsWhitespace(data[*i+4]):
|
||||||
|
blocks--
|
||||||
|
*i += 4
|
||||||
|
|
||||||
|
if blocks == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
*i++
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("unterminated function at %d", *i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipExpression(data []byte, i *int) {
|
||||||
|
parseComment(data, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipWhitespaceNoNewLine(data []byte, i *int) {
|
||||||
|
for *i < len(data) && (data[*i] == ' ' || data[*i] == '\t') {
|
||||||
|
*i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func isLiteral(c byte) bool {
|
func isLiteral(c byte) bool {
|
||||||
if c == '[' || c == ']' {
|
if c == '[' || c == ']' {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if c == '.' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return parsing.IsLiteral(c)
|
return parsing.IsLiteral(c)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,49 @@ multiline = [[
|
|||||||
a multiline
|
a multiline
|
||||||
string
|
string
|
||||||
]]
|
]]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "variables",
|
||||||
|
content: `
|
||||||
|
local foo = "bar"
|
||||||
|
local baz = foo
|
||||||
|
|
||||||
|
hello = baz
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple variables in one line",
|
||||||
|
content: `
|
||||||
|
local foo, bar = "hello", "world"
|
||||||
|
baz = foo
|
||||||
|
test = bar
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "skip expressions",
|
||||||
|
content: `
|
||||||
|
test = (hello == "world") and "foo" or "bar"
|
||||||
|
baz = "123"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "skip expressions in locals",
|
||||||
|
content: `
|
||||||
|
local var1 = "foo"
|
||||||
|
local var2 = var1 == "foo" and "true" or ("false")
|
||||||
|
|
||||||
|
foo = "bar"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "concatenation",
|
||||||
|
content: `
|
||||||
|
local foo = "bar"
|
||||||
|
local baz = "123"
|
||||||
|
hello = "world"..baz
|
||||||
|
baz = foo.." "..baz
|
||||||
|
test = foo .. baz
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -80,6 +123,17 @@ object = {
|
|||||||
hello = "world"
|
hello = "world"
|
||||||
-- this is another comment
|
-- this is another comment
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "content start with comment",
|
||||||
|
content: `
|
||||||
|
foo = "bar"
|
||||||
|
-- this is a comment
|
||||||
|
object = {
|
||||||
|
-- this is another comment
|
||||||
|
hello = "world"
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -91,6 +145,33 @@ list = {
|
|||||||
-- "baz"
|
-- "baz"
|
||||||
"hello"
|
"hello"
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "skip build section",
|
||||||
|
content: `
|
||||||
|
foo = "bar"
|
||||||
|
build = {
|
||||||
|
a = {
|
||||||
|
{
|
||||||
|
content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bar = "baz"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "skip functions",
|
||||||
|
content: `
|
||||||
|
local function test
|
||||||
|
if foo == bar then
|
||||||
|
if hello = world then
|
||||||
|
blah
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
test = "blah"
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -153,6 +234,20 @@ list = {
|
|||||||
"bar",
|
"bar",
|
||||||
-`,
|
-`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "undefined local",
|
||||||
|
wantErr: require.Error,
|
||||||
|
content: `
|
||||||
|
test = hello
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unterminated concatenation",
|
||||||
|
wantErr: require.Error,
|
||||||
|
content: `
|
||||||
|
local foo = "123"
|
||||||
|
hello = foo.. `,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
|||||||
@ -0,0 +1,36 @@
|
|||||||
|
local package_name = "luasyslog"
|
||||||
|
local package_version = "2.0.1"
|
||||||
|
local rockspec_revision = "1"
|
||||||
|
local github_account_name = "lunarmodules"
|
||||||
|
local github_repo_name = package_name
|
||||||
|
|
||||||
|
|
||||||
|
package = package_name
|
||||||
|
version = package_version.."-"..rockspec_revision
|
||||||
|
source = {
|
||||||
|
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||||
|
branch = (package_version == "dev") and "main" or nil,
|
||||||
|
tag = (package_version ~= "dev") and package_version or nil,
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
summary = "Syslog logging for Lua",
|
||||||
|
detailed = [[
|
||||||
|
Addon for LuaLogging to log to the system log on unix systems.
|
||||||
|
Can also be used without LuaLogging to directly write to syslog.
|
||||||
|
]],
|
||||||
|
license = "MIT/X11",
|
||||||
|
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"lualogging >= 1.4.0, < 2.0.0",
|
||||||
|
}
|
||||||
|
build = {
|
||||||
|
type = "builtin",
|
||||||
|
modules = {
|
||||||
|
lsyslog = {
|
||||||
|
sources = "lsyslog.c",
|
||||||
|
},
|
||||||
|
["logging.syslog"] = "syslog.lua",
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user