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

feat(rust): Support workspace.members parsing for Cargo.toml analysis #5285

Merged
merged 15 commits into from
Jan 29, 2024
Merged
65 changes: 43 additions & 22 deletions pkg/fanal/analyzer/language/rust/cargo/cargo.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,39 +155,60 @@
type cargoToml struct {
Dependencies Dependencies `toml:"dependencies"`
Target map[string]map[string]Dependencies `toml:"target"`
Workspace map[string]Dependencies `toml:"workspace"`
Workspace cargoTomlWorkspace `toml:"workspace"`
}

type cargoTomlWorkspace struct {
Dependencies Dependencies `toml:"dependencies"`

Check failure on line 162 in pkg/fanal/analyzer/language/rust/cargo/cargo.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/aquasecurity/) -s blank -s dot (gci)
Members []string `toml:"members"`
}

type Dependencies map[string]interface{}

func (a cargoAnalyzer) parseCargoTOML(fsys fs.FS, path string) (map[string]string, error) {
// Parse Cargo.json
f, err := fsys.Open(path)
if err != nil {
return nil, xerrors.Errorf("file open error: %w", err)
}
defer func() { _ = f.Close() }()

tomlFile := cargoToml{}
deps := map[string]string{}
_, err = toml.NewDecoder(f).Decode(&tomlFile)
if err != nil {
return nil, xerrors.Errorf("toml decode error: %w", err)
}

// There are cases when toml file doesn't include `Dependencies` field (then map will be nil).
// e.g. when only `workspace.Dependencies` are used
// declare `dependencies` to avoid panic
dependencies := Dependencies{}
maps.Copy(dependencies, tomlFile.Dependencies)

// https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies
for _, target := range tomlFile.Target {
maps.Copy(dependencies, target["dependencies"])
deps := map[string]string{}

Check failure on line 173 in pkg/fanal/analyzer/language/rust/cargo/cargo.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/aquasecurity/) -s blank -s dot (gci)
tomlDependencies := func(path string) (cargoToml, error) {
DmitriyLewen marked this conversation as resolved.
Show resolved Hide resolved
// Parse Cargo.toml
f, err := fsys.Open(path)
DmitriyLewen marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return cargoToml{}, xerrors.Errorf("file open error: %w", err)
}
defer func() { _ = f.Close() }()

tomlFile := cargoToml{}

Check failure on line 182 in pkg/fanal/analyzer/language/rust/cargo/cargo.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/aquasecurity/) -s blank -s dot (gci)
_, err = toml.NewDecoder(f).Decode(&tomlFile)
if err != nil {
return cargoToml{}, xerrors.Errorf("toml decode error: %w", err)
}

maps.Copy(dependencies, tomlFile.Dependencies)

Check failure on line 188 in pkg/fanal/analyzer/language/rust/cargo/cargo.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/aquasecurity/) -s blank -s dot (gci)

// https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies

Check failure on line 190 in pkg/fanal/analyzer/language/rust/cargo/cargo.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/aquasecurity/) -s blank -s dot (gci)
for _, target := range tomlFile.Target {
maps.Copy(dependencies, target["dependencies"])
}

// https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#inheriting-a-dependency-from-a-workspace

Check failure on line 195 in pkg/fanal/analyzer/language/rust/cargo/cargo.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/aquasecurity/) -s blank -s dot (gci)
maps.Copy(dependencies, tomlFile.Workspace.Dependencies)
return tomlFile, nil
}

tomlFile, err := tomlDependencies(path)
if err != nil {
return nil, err
}

// https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#inheriting-a-dependency-from-a-workspace
maps.Copy(dependencies, tomlFile.Workspace["dependencies"])
for _, value := range tomlFile.Workspace.Members {
DmitriyLewen marked this conversation as resolved.
Show resolved Hide resolved
newToml := filepath.Join(filepath.Join(filepath.Dir(path), value), types.CargoToml)
DmitriyLewen marked this conversation as resolved.
Show resolved Hide resolved
_, err := tomlDependencies(newToml)
if err != nil {
return nil, err
}
}

for name, value := range dependencies {
switch ver := value.(type) {
Expand Down
Loading