Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/cdx tools #75

Merged
merged 2 commits into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 30 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<!--
Copyright 2023 Interlynk.io

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -28,12 +28,12 @@ go install github.com/interlynk-io/sbomgr@latest
```
other installations [options](#installation)

# SBOM Card
# SBOM Card
[![SBOMCard](https://api.interlynk.io/api/v1/badges?type=hcard&project_group_id=e8e2ba0c-3d04-4a2e-9b37-dca774bd08bd
)](https://app.interlynk.io/customer/products?id=e8e2ba0c-3d04-4a2e-9b37-dca774bd08bd&signed_url_params=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtaakkyTkRRMUxXSTBaR0V0TkdJME9TMWhPVFpqTFRBd09UZGtZMlptTWpabU9TST0iLCJleHAiOm51bGwsInB1ciI6InNoYXJlX2x5bmsvc2hhcmVfbHluayJ9fQ==--6d74d14e40d6676522b1c529d44e4a320f05bcf3d42121e61e1275a1297a3453)

# Basic usage
Search for packages with exact name matching "abbrev".
Search for packages with exact name matching "abbrev".
```sh
sbomgr packages -N 'abbrev' <sbom file or dir>
```
Expand All @@ -48,13 +48,13 @@ Search for packages in air gapped environment for name matching "log4"
export INTERLYNK_DISABLE_VERSION_CHECK=true sbomgr packages -EN 'log4' <sbom file or dir>
```
# Features
- SBOM format agnostic and currently supports searching through SPDX and CycloneDX.
- Blazing Fast :rocket:
- SBOM format agnostic and currently supports searching through SPDX and CycloneDX.
- Blazing Fast :rocket:
- Output search results as [jsonl](https://jsonlines.org/).
- Supports RE2 [regular expressions](https://github.com/google/re2/wiki/Syntax)


# Use cases
# Use cases
`sbomgr` can answer some of the most common SBOM use cases by searching an SBOM file or SBOM repository.

#### How many SBOM and packages exist in the repository?
Expand Down Expand Up @@ -129,7 +129,7 @@ packages_matched: 2

#### extract data using user-defined output
```sh
sbomgr packages -O 'toolv,tooln,pkgn,pkgv' ~/tmp/app.spdx.json
sbomgr packages -O 'toolv,tooln,pkgn,pkgv' ~/tmp/app.spdx.json
2.0.88 Microsoft.SBOMTool Coordinated Packages 229170
2.0.88 Microsoft.SBOMTool chalk 2.4.2
2.0.88 Microsoft.SBOMTool async-settle 1.0.0
Expand Down Expand Up @@ -157,50 +157,51 @@ Matching file count: 3153
Matching package count: 716953
```

# Search flags
# Search flags

## Packages
## Packages
This section explains the flags relevant to the packages search feature.
The packages search takes only a single argument, either a file or a directory. There are man flags which can be specified to control its behaviour.
The packages search takes only a single argument, either a file or a directory. There are man flags which can be specified to control its behaviour.

#### *Match Criteria*
---
- `-N` or `--name` used for package/component name search.
- `-C` or `--cpe` used for package/component cpe search.
- `-P` or `--purl` used for pacakge/component purl search.
- `-H` or `--checksum` used for package/component checksum value search.
- `-C` or `--cpe` used for package/component cpe search.
- `-P` or `--purl` used for pacakge/component purl search.
- `-H` or `--checksum` used for package/component checksum value search.

all of these match criteria are exclusive to each other.
all of these match criteria are exclusive to each other.

#### *Patter Matching*
#### *Patter Matching*
---------
- `-E` or `--extended-regexp` flag can be used to indicate if the match criteria is a regular expression. Syntax supported is https://github.com/google/re2/wiki/Syntax.

#### *Matching Control*
-----
- `-i` or `--ignore-case` case insensitive matching.
- `-i` or `--ignore-case` case insensitive matching.

#### *Output Control*
----
- `-l` or `--license` this includes the license of the package/component in the output.
- `-q` or `--quiet` this suppresses all output of the tool, the return value of the tool is 0 indicating success, if it finds the search criteria.
- `--no-filename` removes the filename from the output.
- `-l` or `--license` this includes the license of the package/component in the output.
- `-q` or `--quiet` this suppresses all output of the tool, the return value of the tool is 0 indicating success, if it finds the search criteria.
- `--no-filename` removes the filename from the output.
- `-j` or `--jsonl` outputs the search results in [jsonl](https://jsonlines.org/).
- `-p` or `--print-errors` includes errors encoundered during searching. Default is to ignore them.
- `-O` or `--output-format` user-defined output format. Options are listed below
- `-p` or `--print-errors` includes errors encoundered during searching. Default is to ignore them.
- `-O` or `--output-format` user-defined output format. Options are listed below
- `filen` - filepath
- `tooln` - tool with which sbom was generated, only prints the first one
- `toolv` - tool version
- `docn` - sbom document name
- `docv` - sbom document version
- `cpe` - package cpe, only prints the first one, indicates how many cpe's exists.
- `purl` - package purl
- `pkgn` - package name
- `pkgn` - package name
- `pkgv` - package version
- `pkgl` - package licenses
- `specn` - spec of the sbom document, spdx or cdx.
- `specn` - spec of the sbom document, spdx or cdx.
- `chkn` - checksum name
- `chkv` - checksum value
- `chkv` - checksum value
- `repo` - repository url

#### *Stats Control*
----
Expand Down Expand Up @@ -273,15 +274,15 @@ We look forward to your contributions, below are a few guidelines on how to subm
- [SBOM Search Tool](https://github.com/interlynk-io/sbomagr) - A tool to grep style semantic search in SBOMs
- [SBOM Explorer](https://github.com/interlynk-io/sbomex) - A tool for discovering and downloading SBOM from a public repository

# Contact
# Contact
We appreciate all feedback. The best ways to get in touch with us:
- :phone: [Live Chat](https://www.interlynk.io/#hs-chat-open)
- 📫 [Email Us](mailto:[email protected])
- 🐛 [Report a bug or enhancement](https://github.com/interlynk-io/sbomex/issues)
- 🐛 [Report a bug or enhancement](https://github.com/interlynk-io/sbomex/issues)
- :x: [Follow us on X](https://twitter.com/InterlynkIo)

# Stargazers

If you like this project, please support us by starring it.
If you like this project, please support us by starring it.

[![Stargazers](https://starchart.cc/interlynk-io/sbomgr.svg)](https://starchart.cc/interlynk-io/sbomgr)
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/spf13/cobra v1.8.1
go.uber.org/zap v1.27.0
gopkg.in/yaml.v2 v2.4.0
sigs.k8s.io/release-utils v0.8.2
sigs.k8s.io/release-utils v0.8.4
)

require (
Expand All @@ -24,18 +24,18 @@ require (
require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/cloudflare/circl v1.3.9 // indirect
github.com/cloudflare/circl v1.4.0 // indirect
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/sys v0.24.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
24 changes: 12 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oM
github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY=
github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ=
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
Expand All @@ -36,8 +36,8 @@ github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3x
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down Expand Up @@ -85,8 +85,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand All @@ -95,8 +95,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -109,8 +109,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
Expand All @@ -136,7 +136,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/release-utils v0.8.2 h1:BKCKabsVkxy/rTRdPeH2t/v2NSU8tMt0fYIWby3hxKQ=
sigs.k8s.io/release-utils v0.8.2/go.mod h1:u2Si4cUBWo2KBAL+7WB8d/HtwgqgssDAHepYu5+dpQY=
sigs.k8s.io/release-utils v0.8.4 h1:4QVr3UgbyY/d9p74LBhg0njSVQofUsAZqYOzVZBhdBw=
sigs.k8s.io/release-utils v0.8.4/go.mod h1:m1bHfscTemQp+z+pLCZnkXih9n0+WukIUU70n6nFnU0=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
26 changes: 23 additions & 3 deletions pkg/search/cdx/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,20 @@ func (doc *cdxDoc) constructResults(pIndices []int) (*results.Result, error) {
}

if doc.doc.Metadata != nil && doc.doc.Metadata.Tools != nil {
tools := *doc.doc.Metadata.Tools.Tools
result.ToolName = tools[0].Name
result.ToolVersion = tools[0].Version
tools := doc.doc.Metadata.Tools
if tools.Tools != nil && len(*tools.Tools) > 0 {
tool := (*tools.Tools)[0]
result.ToolName = tool.Name
result.ToolVersion = tool.Version
} else if tools.Components != nil && len(*tools.Components) > 0 {
tool := (*tools.Components)[0]
result.ToolName = tool.Name
result.ToolVersion = tool.Version
} else if tools.Services != nil && len(*tools.Services) > 0 {
tool := (*tools.Services)[0]
result.ToolName = tool.Name
result.ToolVersion = tool.Version
}
}

return result, nil
Expand All @@ -73,6 +84,15 @@ func (doc *cdxDoc) pkgResults(pIndices []int) []results.Package {
res.CPE = []string{comp.CPE}
}

if comp.ExternalReferences != nil && len(*comp.ExternalReferences) > 0 {
for _, er := range *comp.ExternalReferences {
if er.Type == cydx.ERTypeVCS {
res.Repository = er.URL
break
}
}
}

if comp.Hashes != nil {
for _, c := range *comp.Hashes {
res.Checksums = append(res.Checksums, results.Checksum{
Expand Down
36 changes: 36 additions & 0 deletions pkg/search/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ var OutputFormatOptions = map[string]bool{
"specn": true, //spec name
"chkn": true, //checksum name
"chkv": true, //checksum version
"repo": true, //repository
}

func outputQuiet(r *results.Result, nr *SearchParams) (int, error) {
Expand Down Expand Up @@ -65,6 +66,35 @@ func outputJsonl(r *results.Result, nr *SearchParams) (int, error) {
return matchedPkgCount, fmt.Errorf("no match found")
}

newPackages := []results.Package{}

for _, p := range r.Packages {
newP := results.Package{}
for _, f := range nr.Formats {
switch f {
case "cpe":
newP.CPE = p.CPE
case "purl":
newP.PURL = p.PURL
case "pkgn":
newP.Name = p.Name
case "pkgv":
newP.Version = p.Version
case "pkgl":
newP.Licenses = p.Licenses
case "chkn":
newP.Checksums = p.Checksums
case "chkv":
newP.Checksums = p.Checksums
case "repo":
newP.Repository = p.Repository
}
}
newPackages = append(newPackages, newP)
}

r.Packages = newPackages

b, err := json.Marshal(r)
if err != nil {
return matchedPkgCount, fmt.Errorf("error marshalling json: %w", err)
Expand Down Expand Up @@ -270,6 +300,12 @@ func customOutput(idx int, chkIdx int, r *results.Result, nr *SearchParams) []st
} else {
p = append(p, "[NOCHKV]")
}
case "repo":
if chkIdx >= 0 {
p = append(p, pkg.Repository)
} else {
p = append(p, "[NOREPO]")
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/search/results/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ type Checksum struct {
}

type Package struct {
Name string `json:"name"`
Version string `json:"version"`
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
PURL string `json:"purl,omitempty"`
CPE []string `json:"cpe,omitempty"`
Direct bool `json:"direct,omitempty"`
PathToRoot []string `json:"path_to_root,omitempty"`
Licenses []licenses.LicenseStore `json:"license,omitempty"`
Checksums []Checksum `json:"checksum,omitempty"`
Repository string `json:"repository,omitempty"`
}

type File struct {
Expand Down
5 changes: 3 additions & 2 deletions pkg/search/spdx/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ func (s *spdxDoc) pkgResults(indices []int) []results.Package {
pkgs := make([]results.Package, len(indices))
for i, idx := range indices {
pkgs[i] = results.Package{
Name: s.doc.Packages[idx].PackageName,
Version: s.doc.Packages[idx].PackageVersion,
Name: s.doc.Packages[idx].PackageName,
Version: s.doc.Packages[idx].PackageVersion,
Repository: s.doc.Packages[idx].PackageDownloadLocation,
}

purls := s.Purl(idx)
Expand Down
Loading