github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/dotnet/libman_json.go (about)

     1  package dotnet
     2  
     3  import (
     4  	"encoding/json"
     5  	"path"
     6  	"strings"
     7  
     8  	"github.com/anchore/packageurl-go"
     9  	"github.com/anchore/syft/internal"
    10  	"github.com/anchore/syft/syft/file"
    11  	"github.com/anchore/syft/syft/pkg"
    12  )
    13  
    14  // libmanJSON represents the libman.json file format in ASP.NET projects for describing javascript assets to be downloaded and bundled
    15  // see https://github.com/aspnet/LibraryManager/wiki/libman.json-reference
    16  type libmanJSON struct {
    17  	Location        file.Location `json:"-"`
    18  	Version         string        `json:"version"`
    19  	DefaultProvider string        `json:"defaultProvider"`
    20  	Libraries       []struct {
    21  		Library     string   `json:"library"`
    22  		Files       []string `json:"files"`
    23  		Destination string   `json:"destination"`
    24  		Provider    string   `json:"provider,omitempty"`
    25  	} `json:"libraries"`
    26  }
    27  
    28  func (l *libmanJSON) packages() []pkg.Package {
    29  	if l == nil {
    30  		return nil
    31  	}
    32  
    33  	var pkgs []pkg.Package
    34  	for _, lib := range l.Libraries {
    35  		if lib.Provider == "filesystem" {
    36  			// there is no name and version with filesystem providers
    37  			continue
    38  		}
    39  		fields := strings.Split(lib.Library, "@")
    40  		if len(fields) != 2 {
    41  			continue
    42  		}
    43  
    44  		name := fields[0]
    45  		version := fields[1]
    46  
    47  		p := pkg.Package{
    48  			Name:      name,
    49  			Version:   version,
    50  			Locations: file.NewLocationSet(l.Location),
    51  			Type:      pkg.NpmPkg,
    52  			PURL: packageurl.NewPackageURL(
    53  				packageurl.TypeNPM,
    54  				"",
    55  				name,
    56  				version,
    57  				nil,
    58  				"",
    59  			).ToString(),
    60  			Language: pkg.JavaScript,
    61  		}
    62  
    63  		p.SetID()
    64  		pkgs = append(pkgs, p)
    65  	}
    66  
    67  	return pkgs
    68  }
    69  
    70  func newLibmanJSON(reader file.LocationReadCloser) (*libmanJSON, error) {
    71  	var doc libmanJSON
    72  	dec := json.NewDecoder(reader)
    73  	if err := dec.Decode(&doc); err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	for i := range doc.Libraries {
    78  		l := &doc.Libraries[i]
    79  		if l.Provider == "" {
    80  			l.Provider = doc.DefaultProvider
    81  		}
    82  	}
    83  
    84  	doc.Location = reader.Location
    85  
    86  	return &doc, nil
    87  }
    88  
    89  func findLibmanJSON(resolver file.Resolver, depsJSON file.Location) (*libmanJSON, error) {
    90  	parent := path.Dir(depsJSON.RealPath)
    91  	loc := resolver.RelativeFileByPath(depsJSON, path.Join(parent, "libman.json"))
    92  	if loc == nil {
    93  		return nil, nil
    94  	}
    95  
    96  	reader, err := resolver.FileContentsByLocation(*loc)
    97  	defer internal.CloseAndLogError(reader, loc.RealPath)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  
   102  	lj, err := newLibmanJSON(file.NewLocationReadCloser(*loc, reader))
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  
   107  	return lj, nil
   108  }