go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers-sdk/v1/lr/resolve.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package lr
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"path"
    10  	"strings"
    11  )
    12  
    13  func Resolve(filePath string, readFile func(path string) ([]byte, error)) (*LR, error) {
    14  	raw, err := readFile(filePath)
    15  	if err != nil {
    16  		return nil, err
    17  	}
    18  
    19  	anchorPath := path.Dir(filePath)
    20  
    21  	res, err := Parse(string(raw))
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  
    26  	res.imports = make(map[string]map[string]struct{})
    27  	res.packPaths = map[string]string{}
    28  	importMap := map[string]map[string]*Resource{
    29  		"": {},
    30  	}
    31  	for _, r := range res.Resources {
    32  		importMap[""][r.ID] = r
    33  	}
    34  	for i := range res.Imports {
    35  		// note: we do not recurse into these imports; we only need to know
    36  		// about the things that the import exposes, not about its dependencies
    37  		importPath := res.Imports[i]
    38  		packName := strings.TrimSuffix(path.Base(importPath), ".lr")
    39  		relPath := path.Join(anchorPath, importPath)
    40  
    41  		raw, err := readFile(relPath)
    42  		if err != nil {
    43  			return nil, err
    44  		}
    45  
    46  		childLR, err := Parse(string(raw))
    47  		if err != nil {
    48  			return nil, err
    49  		}
    50  
    51  		resources := map[string]struct{}{}
    52  		importMap[packName] = map[string]*Resource{}
    53  		for i := range childLR.Resources {
    54  			resource := childLR.Resources[i]
    55  			resources[resource.ID] = struct{}{}
    56  			importMap[packName][resource.ID] = resource
    57  		}
    58  
    59  		res.imports[packName] = resources
    60  
    61  		goPkg := childLR.Options["go_package"]
    62  		if goPkg == "" {
    63  			return nil, errors.New("cannot find name of the go package in " + importPath + " - make sure you set the go_package name")
    64  		}
    65  		res.packPaths[packName] = goPkg
    66  	}
    67  
    68  	res.aliases = map[string]*Resource{}
    69  	for _, a := range res.Aliases {
    70  		var pack string
    71  		var resourceName string
    72  
    73  		if _, ok := importMap[""][a.Type.Type]; ok {
    74  			pack = ""
    75  			resourceName = a.Type.Type
    76  		} else {
    77  			pack, resourceName, ok = strings.Cut(a.Type.Type, ".")
    78  			if !ok {
    79  				pack = ""
    80  				resourceName = a.Type.Type
    81  			}
    82  		}
    83  
    84  		found := false
    85  		p, ok := importMap[pack]
    86  		if ok {
    87  			r, ok := p[resourceName]
    88  			if ok {
    89  				found = true
    90  			}
    91  			res.aliases[a.Definition.Type] = r
    92  		}
    93  
    94  		if !found {
    95  			return nil, fmt.Errorf("%s was aliased but not imported", a.Type.Type)
    96  		}
    97  	}
    98  
    99  	res.Imports = nil
   100  
   101  	return res, nil
   102  }