github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/lua/parse_rockspec.go (about) 1 package lua 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/anchore/syft/internal/log" 9 "github.com/anchore/syft/syft/artifact" 10 "github.com/anchore/syft/syft/file" 11 "github.com/anchore/syft/syft/pkg" 12 "github.com/anchore/syft/syft/pkg/cataloger/generic" 13 ) 14 15 type luaRocksPackage struct { 16 Name string 17 Version string 18 License string 19 Homepage string 20 Description string 21 Dependencies map[string]string 22 Repository repository 23 } 24 25 type repository struct { 26 URL string 27 } 28 29 // parseRockspec parses a package.rockspec and returns the discovered Lua packages. 30 func parseRockspec(ctx context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 31 doc, err := parseRockspecData(reader) 32 if err != nil { 33 log.WithFields("error", err).Trace("unable to parse Rockspec app") 34 return nil, nil, fmt.Errorf("unable to parse Rockspec app: %w", err) 35 } 36 37 var name, version, license, homepage, description, url string 38 var dependencies map[string]string 39 40 for _, node := range doc.value { 41 switch node.key { 42 case "package": 43 name = node.String() 44 case "version": 45 version = node.String() 46 case "source": 47 for _, child := range node.Slice() { 48 if child.key == "url" { 49 url = child.String() 50 break 51 } 52 } 53 case "description": 54 for _, child := range node.Slice() { 55 switch child.key { 56 case "summary": 57 description = child.String() 58 case "homepage": 59 homepage = child.String() 60 case "license": 61 license = strings.ReplaceAll(child.String(), " ", "-") 62 } 63 } 64 case "dependencies": 65 if dependencies == nil { 66 dependencies = make(map[string]string) 67 } 68 for _, child := range node.Slice() { 69 depName, depVersion := parseDependency(child.String()) 70 if depName != "" { 71 dependencies[depName] = depVersion 72 } 73 } 74 } 75 } 76 77 p := newLuaRocksPackage( 78 ctx, 79 resolver, 80 luaRocksPackage{ 81 Name: name, 82 Version: version, 83 License: license, 84 Repository: repository{ 85 URL: url, 86 }, 87 Homepage: homepage, 88 Description: description, 89 Dependencies: dependencies, 90 }, 91 reader.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), 92 ) 93 94 return []pkg.Package{p}, nil, nil 95 } 96 97 // parseDependency extracts the package name and version constraint from a dependency string. 98 // Examples: 99 // - "lua >= 5.1" -> ("lua", ">= 5.1") 100 // - "lpeg" -> ("lpeg", "") 101 // - "lualogging >= 1.4.0, < 2.0.0" -> ("lualogging", ">= 1.4.0, < 2.0.0") 102 func parseDependency(dep string) (name string, version string) { 103 dep = strings.TrimSpace(dep) 104 if dep == "" { 105 return "", "" 106 } 107 108 // Find the first space which separates package name from version constraint 109 parts := strings.SplitN(dep, " ", 2) 110 name = strings.TrimSpace(parts[0]) 111 112 if len(parts) == 2 { 113 version = strings.TrimSpace(parts[1]) 114 } 115 116 return name, version 117 }