mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
Fix for errors+failures parsing package.json
closes: #230 Signed-off-by: Toure Dunnon <toure.dunnon@anchore.com>
This commit is contained in:
parent
931c796158
commit
15379d1075
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
|
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
|
||||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b
|
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b
|
||||||
github.com/anchore/stereoscope v0.0.0-20200925184903-c82da54e98fe
|
github.com/anchore/stereoscope v0.0.0-20200925184903-c82da54e98fe
|
||||||
|
github.com/apex/log v1.3.0
|
||||||
github.com/bmatcuk/doublestar v1.3.1
|
github.com/bmatcuk/doublestar v1.3.1
|
||||||
github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
|
github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
|
|||||||
@ -27,6 +27,7 @@ type PackageJSON struct {
|
|||||||
Homepage string `json:"homepage"`
|
Homepage string `json:"homepage"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Dependencies map[string]string `json:"dependencies"`
|
Dependencies map[string]string `json:"dependencies"`
|
||||||
|
Repository Repository `json:"repository"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Author struct {
|
type Author struct {
|
||||||
@ -35,36 +36,39 @@ type Author struct {
|
|||||||
URL string `json:"url" mapstruct:"url"`
|
URL string `json:"url" mapstruct:"url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// match example: "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)"
|
||||||
|
// ---> name: "Isaac Z. Schlueter" email: "i@izs.me" url: "http://blog.izs.me"
|
||||||
var authorPattern = regexp.MustCompile(`^\s*(?P<name>[^<(]*)(\s+<(?P<email>.*)>)?(\s\((?P<url>.*)\))?\s*$`)
|
var authorPattern = regexp.MustCompile(`^\s*(?P<name>[^<(]*)(\s+<(?P<email>.*)>)?(\s\((?P<url>.*)\))?\s*$`)
|
||||||
|
|
||||||
|
// This method implements the UnmarshalJSON interface to help normalize
|
||||||
|
// the json structure.
|
||||||
func (a *Author) UnmarshalJSON(b []byte) error {
|
func (a *Author) UnmarshalJSON(b []byte) error {
|
||||||
var authorStr string
|
var authorStr string
|
||||||
|
var fields map[string]string
|
||||||
|
var author Author
|
||||||
|
|
||||||
if err := json.Unmarshal(b, &authorStr); err != nil {
|
if err := json.Unmarshal(b, &authorStr); err != nil {
|
||||||
// string parsing did not work, assume a map was given
|
// string parsing did not work, assume a map was given
|
||||||
// for more information: https://docs.npmjs.com/files/package.json#people-fields-author-contributors
|
// for more information: https://docs.npmjs.com/files/package.json#people-fields-author-contributors
|
||||||
var fields map[string]string
|
|
||||||
var author Author
|
|
||||||
if err := json.Unmarshal(b, &fields); err != nil {
|
if err := json.Unmarshal(b, &fields); err != nil {
|
||||||
return fmt.Errorf("unable to parse package.json author: %w", err)
|
return fmt.Errorf("unable to parse package.json author: %w", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// parse out "name <email> (url)" into an Author struct
|
||||||
|
fields = internal.MatchCaptureGroups(authorPattern, authorStr)
|
||||||
|
}
|
||||||
|
|
||||||
// translate the map into a structure
|
// translate the map into a structure
|
||||||
if err := mapstructure.Decode(fields, &author); err != nil {
|
if err := mapstructure.Decode(fields, &author); err != nil {
|
||||||
return fmt.Errorf("unable to decode package.json author: %w", err)
|
return fmt.Errorf("unable to decode package.json author: %w", err)
|
||||||
}
|
}
|
||||||
*a = author
|
|
||||||
} else {
|
|
||||||
// parse out "name <email> (url)" into an Author struct
|
|
||||||
var fields = internal.MatchCaptureGroups(authorPattern, authorStr)
|
|
||||||
*a = Author{
|
|
||||||
Name: fields["name"],
|
|
||||||
Email: fields["email"],
|
|
||||||
URL: fields["url"],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Name == "" {
|
*a = author
|
||||||
return fmt.Errorf("package.json author name is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -102,6 +106,7 @@ func parsePackageJSON(_ string, reader io.Reader) ([]pkg.Package, error) {
|
|||||||
Metadata: pkg.NpmMetadata{
|
Metadata: pkg.NpmMetadata{
|
||||||
Author: p.Author.String(),
|
Author: p.Author.String(),
|
||||||
Homepage: p.Homepage,
|
Homepage: p.Homepage,
|
||||||
|
URL: p.Repository.URL,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ func TestParsePackageJSON(t *testing.T) {
|
|||||||
Metadata: pkg.NpmMetadata{
|
Metadata: pkg.NpmMetadata{
|
||||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||||
Homepage: "https://docs.npmjs.com/",
|
Homepage: "https://docs.npmjs.com/",
|
||||||
|
URL: "https://github.com/npm/cli",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -38,6 +39,7 @@ func TestParsePackageJSON(t *testing.T) {
|
|||||||
Metadata: pkg.NpmMetadata{
|
Metadata: pkg.NpmMetadata{
|
||||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||||
Homepage: "https://docs.npmjs.com/",
|
Homepage: "https://docs.npmjs.com/",
|
||||||
|
URL: "https://github.com/npm/cli",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -62,6 +64,7 @@ func TestParsePackageJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range deep.Equal(actual[0], test.ExpectedPkg) {
|
for _, d := range deep.Equal(actual[0], test.ExpectedPkg) {
|
||||||
|
|
||||||
t.Errorf("diff: %+v", d)
|
t.Errorf("diff: %+v", d)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -8,5 +8,9 @@
|
|||||||
"email": "i@izs.me",
|
"email": "i@izs.me",
|
||||||
"url": "http://blog.izs.me"
|
"url": "http://blog.izs.me"
|
||||||
},
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/npm/cli"
|
||||||
|
},
|
||||||
"license": "Artistic-2.0"
|
"license": "Artistic-2.0"
|
||||||
}
|
}
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package pkg
|
|
||||||
|
|
||||||
type MetadataType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
UnknownMetadataType MetadataType = "UnknownMetadata"
|
|
||||||
ApkMetadataType MetadataType = "apk-metadata"
|
|
||||||
DpkgMetadataType MetadataType = "dpkg-metadata"
|
|
||||||
GemgMetadataType MetadataType = "gem-metadata"
|
|
||||||
RpmdbMetadataType MetadataType = "rpmdb-metadata"
|
|
||||||
)
|
|
||||||
@ -9,4 +9,5 @@ type NpmMetadata struct {
|
|||||||
License string `mapstructure:"license" json:"license"`
|
License string `mapstructure:"license" json:"license"`
|
||||||
Homepage string `mapstructure:"homepage" json:"homepage"`
|
Homepage string `mapstructure:"homepage" json:"homepage"`
|
||||||
Description string `mapstructure:"description" json:"description"`
|
Description string `mapstructure:"description" json:"description"`
|
||||||
|
URL string `mapstructure:"url" json:"url"`
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user