From 8b28c7d45169571987bdcc3a5a5572d2fa77c3fa Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Sun, 29 Oct 2023 14:47:06 -0400 Subject: [PATCH 01/27] adding packages.props and Directory.packages.props parser --- pkg/nuget/packages_props/parse.go | 92 +++++++++++++++++++ pkg/nuget/packages_props/parse_test.go | 66 +++++++++++++ .../testdata/Directory.Packages.props | 7 ++ .../testdata/no_item_group.props | 11 +++ .../packages_props/testdata/no_project.props | 10 ++ .../packages_props/testdata/packages.props | 11 +++ 6 files changed, 197 insertions(+) create mode 100644 pkg/nuget/packages_props/parse.go create mode 100644 pkg/nuget/packages_props/parse_test.go create mode 100644 pkg/nuget/packages_props/testdata/Directory.Packages.props create mode 100644 pkg/nuget/packages_props/testdata/no_item_group.props create mode 100644 pkg/nuget/packages_props/testdata/no_project.props create mode 100644 pkg/nuget/packages_props/testdata/packages.props diff --git a/pkg/nuget/packages_props/parse.go b/pkg/nuget/packages_props/parse.go new file mode 100644 index 00000000..ddb9148a --- /dev/null +++ b/pkg/nuget/packages_props/parse.go @@ -0,0 +1,92 @@ +package config + +import ( + "encoding/xml" + "golang.org/x/xerrors" + + dio "github.com/aquasecurity/go-dep-parser/pkg/io" + "github.com/aquasecurity/go-dep-parser/pkg/types" + "github.com/aquasecurity/go-dep-parser/pkg/utils" +) + + + + +type propsPackageEntry struct{ + Version string `xml:"Version,attr"` + UpdatePackageName string `xml:"Update,attr"` + IncludePackageName string `xml:"Include,attr"` +} + +type propsPackageReferenceEntry struct { + XMLName xml.Name `xml:"PackageReference"` + propsPackageEntry +} + +type propsPackageVersionEntry struct { + XMLName xml.Name `xml:"PackageVersion"` + propsPackageEntry +} + +type propsItemGroup struct { + XMLName xml.Name `xml:"ItemGroup"` + ReferencePackages []propsPackageReferenceEntry `xml:"PackageReference"` + VersionPackages []propsPackageVersionEntry `xml:"PackageVersion"` +} + +type propsProject struct { + XMLName xml.Name `xml:"Project"` + ItemGroups []propsItemGroup `xml:"ItemGroup"` +} + +type Parser struct{} + +func NewParser() types.Parser { + return &Parser{} +} + +func (p *Parser) addPackage(libs* []types.Library, pkg propsPackageEntry) { + if ((len(pkg.UpdatePackageName) == 0 && len(pkg.IncludePackageName) == 0 ) || len(pkg.Version) == 0){ + return + } + var lib types.Library + // Update attribute is considered legacy, so preferring Include + if (len(pkg.IncludePackageName) > 0 ){ + lib = types.Library{ + Name: pkg.IncludePackageName, + Version: pkg.Version, + } + }else{ + lib = types.Library{ + Name: pkg.UpdatePackageName, + Version: pkg.Version, + } + } + *libs = append(*libs, lib) +} + + +func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, error) { + var configData propsProject + if err := xml.NewDecoder(r).Decode(&configData); err != nil { + return nil, nil, xerrors.Errorf("failed to decode .props file: %w", err) + } + // https://github.com/dotnet/roslyn-tools/blob/8617f451b13e3dc29751cc78109f32ec73eeedb0/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L488 + // Based on this documentation both legacy packages.props and Directory.packages.props are supported + + libs := make([]types.Library, 0) + for _, itemGroup := range configData.ItemGroups{ + for _, refPkg := range itemGroup.ReferencePackages{ + var pkg = propsPackageEntry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} + p.addPackage(&libs, pkg) + } + + for _, verPkg := range itemGroup.VersionPackages{ + var pkg = propsPackageEntry{verPkg.Version, verPkg.UpdatePackageName, verPkg.IncludePackageName} + p.addPackage(&libs, pkg) + } + } + return utils.UniqueLibraries(libs), nil, nil +} + + diff --git a/pkg/nuget/packages_props/parse_test.go b/pkg/nuget/packages_props/parse_test.go new file mode 100644 index 00000000..e15d45a1 --- /dev/null +++ b/pkg/nuget/packages_props/parse_test.go @@ -0,0 +1,66 @@ +package config_test + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/aquasecurity/go-dep-parser/pkg/nuget/packages_props" + "github.com/aquasecurity/go-dep-parser/pkg/types" +) + +func TestParse(t *testing.T) { + tests := []struct { + name string // Test input file + inputFile string + want []types.Library + wantErr string + }{ + { + name: "PackagesProps", + inputFile: "testdata/packages.props", + want: []types.Library{ + {Name: "Microsoft.Extensions.Configuration", Version: "2.1.1"}, + {Name: "Microsoft.Extensions.DependencyInjection.Abstractions", Version: "2.2.1"}, + {Name: "Microsoft.Extensions.Http", Version: "3.2.1"}, + }, + }, + { + name: "DirectoryPackagesProps", + inputFile: "testdata/Directory.Packages.props", + want: []types.Library{ + {Name: "PackageOne", Version: "6.2.3"}, + {Name: "PackageTwo", Version: "6.0.0"}, + {Name: "PackageThree", Version: "2.4.1"}, + }, + }, + { + name: "NoProjectInXMLStructure", + inputFile: "testdata/no_project.props", + wantErr: "failed to decode .props file: expected element type but have ", + }, + { + name: "NoItemGroupInXMLStructure", + inputFile: "testdata/no_item_group.props", + want: []types.Library{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.inputFile) + require.NoError(t, err) + + got, _, err := config.NewParser().Parse(f) + if tt.wantErr != "" { + require.NotNil(t, err) + assert.Contains(t, err.Error(), tt.wantErr) + return + } + + assert.NoError(t, err) + assert.ElementsMatch(t, tt.want, got) + }) + } +} diff --git a/pkg/nuget/packages_props/testdata/Directory.Packages.props b/pkg/nuget/packages_props/testdata/Directory.Packages.props new file mode 100644 index 00000000..0f39c0a2 --- /dev/null +++ b/pkg/nuget/packages_props/testdata/Directory.Packages.props @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/pkg/nuget/packages_props/testdata/no_item_group.props b/pkg/nuget/packages_props/testdata/no_item_group.props new file mode 100644 index 00000000..aa3b2813 --- /dev/null +++ b/pkg/nuget/packages_props/testdata/no_item_group.props @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/pkg/nuget/packages_props/testdata/no_project.props b/pkg/nuget/packages_props/testdata/no_project.props new file mode 100644 index 00000000..041498a6 --- /dev/null +++ b/pkg/nuget/packages_props/testdata/no_project.props @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/pkg/nuget/packages_props/testdata/packages.props b/pkg/nuget/packages_props/testdata/packages.props new file mode 100644 index 00000000..7ec6d02a --- /dev/null +++ b/pkg/nuget/packages_props/testdata/packages.props @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file From 23ab781663e40dbfc210dbf6d8f81d3714a2e1e9 Mon Sep 17 00:00:00 2001 From: yuriShafet <5830215+yuriShafet@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:12:09 -0400 Subject: [PATCH 02/27] Better error message Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> --- pkg/nuget/packages_props/parse.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/nuget/packages_props/parse.go b/pkg/nuget/packages_props/parse.go index ddb9148a..22f70abd 100644 --- a/pkg/nuget/packages_props/parse.go +++ b/pkg/nuget/packages_props/parse.go @@ -69,7 +69,7 @@ func (p *Parser) addPackage(libs* []types.Library, pkg propsPackageEntry) { func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, error) { var configData propsProject if err := xml.NewDecoder(r).Decode(&configData); err != nil { - return nil, nil, xerrors.Errorf("failed to decode .props file: %w", err) + return nil, nil, xerrors.Errorf("failed to decode '*packages.props' file: %w", err) } // https://github.com/dotnet/roslyn-tools/blob/8617f451b13e3dc29751cc78109f32ec73eeedb0/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L488 // Based on this documentation both legacy packages.props and Directory.packages.props are supported From 5d4957f39d5f632570a4b50fcb8d171ba57be30c Mon Sep 17 00:00:00 2001 From: yuriShafet <5830215+yuriShafet@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:13:48 -0400 Subject: [PATCH 03/27] Replacing ElementsMatch with Equal in tests Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> --- pkg/nuget/packages_props/parse_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/nuget/packages_props/parse_test.go b/pkg/nuget/packages_props/parse_test.go index e15d45a1..6d87653f 100644 --- a/pkg/nuget/packages_props/parse_test.go +++ b/pkg/nuget/packages_props/parse_test.go @@ -60,7 +60,7 @@ func TestParse(t *testing.T) { } assert.NoError(t, err) - assert.ElementsMatch(t, tt.want, got) + assert.Equal(t, tt.want, got) }) } } From 48d585db7b3e5ab46019ba651ac84701db98f225 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Wed, 1 Nov 2023 22:49:43 -0400 Subject: [PATCH 04/27] renaming package folder --- .../parse.go | 40 ++++++++----------- .../parse_test.go | 11 ++--- .../testdata/Directory.Packages.props | 0 .../testdata/no_item_group.props | 0 .../testdata/no_project.props | 0 .../testdata/packages.props | 0 6 files changed, 20 insertions(+), 31 deletions(-) rename pkg/nuget/{packages_props => packagesprops}/parse.go (65%) rename pkg/nuget/{packages_props => packagesprops}/parse_test.go (80%) rename pkg/nuget/{packages_props => packagesprops}/testdata/Directory.Packages.props (100%) rename pkg/nuget/{packages_props => packagesprops}/testdata/no_item_group.props (100%) rename pkg/nuget/{packages_props => packagesprops}/testdata/no_project.props (100%) rename pkg/nuget/{packages_props => packagesprops}/testdata/packages.props (100%) diff --git a/pkg/nuget/packages_props/parse.go b/pkg/nuget/packagesprops/parse.go similarity index 65% rename from pkg/nuget/packages_props/parse.go rename to pkg/nuget/packagesprops/parse.go index 22f70abd..b7e07964 100644 --- a/pkg/nuget/packages_props/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -2,6 +2,7 @@ package config import ( "encoding/xml" + "golang.org/x/xerrors" dio "github.com/aquasecurity/go-dep-parser/pkg/io" @@ -9,33 +10,29 @@ import ( "github.com/aquasecurity/go-dep-parser/pkg/utils" ) - - - -type propsPackageEntry struct{ - Version string `xml:"Version,attr"` - UpdatePackageName string `xml:"Update,attr"` - IncludePackageName string `xml:"Include,attr"` +type propsPackageEntry struct { + Version string `xml:"Version,attr"` + UpdatePackageName string `xml:"Update,attr"` + IncludePackageName string `xml:"Include,attr"` } type propsPackageReferenceEntry struct { - XMLName xml.Name `xml:"PackageReference"` + xml.Name `xml:"PackageReference"` propsPackageEntry } type propsPackageVersionEntry struct { - XMLName xml.Name `xml:"PackageVersion"` + xml.Name `xml:"PackageVersion"` propsPackageEntry } type propsItemGroup struct { - XMLName xml.Name `xml:"ItemGroup"` + xml.Name `xml:"ItemGroup"` ReferencePackages []propsPackageReferenceEntry `xml:"PackageReference"` - VersionPackages []propsPackageVersionEntry `xml:"PackageVersion"` + VersionPackages []propsPackageVersionEntry `xml:"PackageVersion"` } type propsProject struct { - XMLName xml.Name `xml:"Project"` ItemGroups []propsItemGroup `xml:"ItemGroup"` } @@ -45,18 +42,18 @@ func NewParser() types.Parser { return &Parser{} } -func (p *Parser) addPackage(libs* []types.Library, pkg propsPackageEntry) { - if ((len(pkg.UpdatePackageName) == 0 && len(pkg.IncludePackageName) == 0 ) || len(pkg.Version) == 0){ +func (p *Parser) addPackage(libs *[]types.Library, pkg propsPackageEntry) { + if (len(pkg.UpdatePackageName) == 0 && len(pkg.IncludePackageName) == 0) || len(pkg.Version) == 0 { return } var lib types.Library // Update attribute is considered legacy, so preferring Include - if (len(pkg.IncludePackageName) > 0 ){ + if len(pkg.IncludePackageName) > 0 { lib = types.Library{ Name: pkg.IncludePackageName, Version: pkg.Version, } - }else{ + } else { lib = types.Library{ Name: pkg.UpdatePackageName, Version: pkg.Version, @@ -65,28 +62,25 @@ func (p *Parser) addPackage(libs* []types.Library, pkg propsPackageEntry) { *libs = append(*libs, lib) } - func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, error) { var configData propsProject if err := xml.NewDecoder(r).Decode(&configData); err != nil { - return nil, nil, xerrors.Errorf("failed to decode '*packages.props' file: %w", err) + return nil, nil, xerrors.Errorf("failed to decode '*.packages.props' file: %w", err) } // https://github.com/dotnet/roslyn-tools/blob/8617f451b13e3dc29751cc78109f32ec73eeedb0/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L488 // Based on this documentation both legacy packages.props and Directory.packages.props are supported libs := make([]types.Library, 0) - for _, itemGroup := range configData.ItemGroups{ - for _, refPkg := range itemGroup.ReferencePackages{ + for _, itemGroup := range configData.ItemGroups { + for _, refPkg := range itemGroup.ReferencePackages { var pkg = propsPackageEntry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} p.addPackage(&libs, pkg) } - for _, verPkg := range itemGroup.VersionPackages{ + for _, verPkg := range itemGroup.VersionPackages { var pkg = propsPackageEntry{verPkg.Version, verPkg.UpdatePackageName, verPkg.IncludePackageName} p.addPackage(&libs, pkg) } } return utils.UniqueLibraries(libs), nil, nil } - - diff --git a/pkg/nuget/packages_props/parse_test.go b/pkg/nuget/packagesprops/parse_test.go similarity index 80% rename from pkg/nuget/packages_props/parse_test.go rename to pkg/nuget/packagesprops/parse_test.go index 6d87653f..c64e3df5 100644 --- a/pkg/nuget/packages_props/parse_test.go +++ b/pkg/nuget/packagesprops/parse_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/aquasecurity/go-dep-parser/pkg/nuget/packages_props" + config "github.com/aquasecurity/go-dep-parser/pkg/nuget/packagesprops" "github.com/aquasecurity/go-dep-parser/pkg/types" ) @@ -36,15 +36,10 @@ func TestParse(t *testing.T) { {Name: "PackageThree", Version: "2.4.1"}, }, }, - { - name: "NoProjectInXMLStructure", - inputFile: "testdata/no_project.props", - wantErr: "failed to decode .props file: expected element type but have ", - }, { name: "NoItemGroupInXMLStructure", inputFile: "testdata/no_item_group.props", - want: []types.Library{}, + want: []types.Library{}, }, } for _, tt := range tests { @@ -60,7 +55,7 @@ func TestParse(t *testing.T) { } assert.NoError(t, err) - assert.Equal(t, tt.want, got) + assert.ElementsMatch(t, tt.want, got) }) } } diff --git a/pkg/nuget/packages_props/testdata/Directory.Packages.props b/pkg/nuget/packagesprops/testdata/Directory.Packages.props similarity index 100% rename from pkg/nuget/packages_props/testdata/Directory.Packages.props rename to pkg/nuget/packagesprops/testdata/Directory.Packages.props diff --git a/pkg/nuget/packages_props/testdata/no_item_group.props b/pkg/nuget/packagesprops/testdata/no_item_group.props similarity index 100% rename from pkg/nuget/packages_props/testdata/no_item_group.props rename to pkg/nuget/packagesprops/testdata/no_item_group.props diff --git a/pkg/nuget/packages_props/testdata/no_project.props b/pkg/nuget/packagesprops/testdata/no_project.props similarity index 100% rename from pkg/nuget/packages_props/testdata/no_project.props rename to pkg/nuget/packagesprops/testdata/no_project.props diff --git a/pkg/nuget/packages_props/testdata/packages.props b/pkg/nuget/packagesprops/testdata/packages.props similarity index 100% rename from pkg/nuget/packages_props/testdata/packages.props rename to pkg/nuget/packagesprops/testdata/packages.props From 3f7940f64498bba93070b91288eb26678649e934 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Wed, 1 Nov 2023 23:13:34 -0400 Subject: [PATCH 05/27] parsePkg function now returns parsed lib --- pkg/nuget/packagesprops/parse.go | 35 +++++++++++++-------------- pkg/nuget/packagesprops/parse_test.go | 12 ++++----- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index b7e07964..2fb9ddc5 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -42,24 +42,17 @@ func NewParser() types.Parser { return &Parser{} } -func (p *Parser) addPackage(libs *[]types.Library, pkg propsPackageEntry) { - if (len(pkg.UpdatePackageName) == 0 && len(pkg.IncludePackageName) == 0) || len(pkg.Version) == 0 { - return - } - var lib types.Library +func parsePackage(pkg propsPackageEntry) types.Library { // Update attribute is considered legacy, so preferring Include - if len(pkg.IncludePackageName) > 0 { - lib = types.Library{ - Name: pkg.IncludePackageName, - Version: pkg.Version, - } - } else { - lib = types.Library{ - Name: pkg.UpdatePackageName, - Version: pkg.Version, - } + name := pkg.UpdatePackageName + if pkg.IncludePackageName != "" { + name = pkg.IncludePackageName + } + return types.Library{ + ID: utils.PackageID(name, pkg.Version), + Name: name, + Version: pkg.Version, } - *libs = append(*libs, lib) } func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, error) { @@ -74,12 +67,18 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, for _, itemGroup := range configData.ItemGroups { for _, refPkg := range itemGroup.ReferencePackages { var pkg = propsPackageEntry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} - p.addPackage(&libs, pkg) + var lib = parsePackage(pkg) + if len(lib.Name) > 0 && len(lib.Version) > 0 { + libs = append(libs, lib) + } } for _, verPkg := range itemGroup.VersionPackages { var pkg = propsPackageEntry{verPkg.Version, verPkg.UpdatePackageName, verPkg.IncludePackageName} - p.addPackage(&libs, pkg) + var lib = parsePackage(pkg) + if len(lib.Name) > 0 && len(lib.Version) > 0 { + libs = append(libs, lib) + } } } return utils.UniqueLibraries(libs), nil, nil diff --git a/pkg/nuget/packagesprops/parse_test.go b/pkg/nuget/packagesprops/parse_test.go index c64e3df5..b7a00e3c 100644 --- a/pkg/nuget/packagesprops/parse_test.go +++ b/pkg/nuget/packagesprops/parse_test.go @@ -22,18 +22,18 @@ func TestParse(t *testing.T) { name: "PackagesProps", inputFile: "testdata/packages.props", want: []types.Library{ - {Name: "Microsoft.Extensions.Configuration", Version: "2.1.1"}, - {Name: "Microsoft.Extensions.DependencyInjection.Abstractions", Version: "2.2.1"}, - {Name: "Microsoft.Extensions.Http", Version: "3.2.1"}, + {Name: "Microsoft.Extensions.Configuration", Version: "2.1.1", ID: "Microsoft.Extensions.Configuration@2.1.1"}, + {Name: "Microsoft.Extensions.DependencyInjection.Abstractions", Version: "2.2.1", ID: "Microsoft.Extensions.DependencyInjection.Abstractions@2.2.1"}, + {Name: "Microsoft.Extensions.Http", Version: "3.2.1", ID: "Microsoft.Extensions.Http@3.2.1"}, }, }, { name: "DirectoryPackagesProps", inputFile: "testdata/Directory.Packages.props", want: []types.Library{ - {Name: "PackageOne", Version: "6.2.3"}, - {Name: "PackageTwo", Version: "6.0.0"}, - {Name: "PackageThree", Version: "2.4.1"}, + {Name: "PackageOne", Version: "6.2.3", ID: "PackageOne@6.2.3"}, + {Name: "PackageTwo", Version: "6.0.0", ID: "PackageTwo@6.0.0"}, + {Name: "PackageThree", Version: "2.4.1", ID: "PackageThree@2.4.1"}, }, }, { From 807c1088ff1d666d75f3a88b78aaa63b0ba1df32 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Wed, 1 Nov 2023 23:16:35 -0400 Subject: [PATCH 06/27] removing redundant structs --- pkg/nuget/packagesprops/parse.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 2fb9ddc5..5e6b0ee9 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -16,20 +16,10 @@ type propsPackageEntry struct { IncludePackageName string `xml:"Include,attr"` } -type propsPackageReferenceEntry struct { - xml.Name `xml:"PackageReference"` - propsPackageEntry -} - -type propsPackageVersionEntry struct { - xml.Name `xml:"PackageVersion"` - propsPackageEntry -} - type propsItemGroup struct { xml.Name `xml:"ItemGroup"` - ReferencePackages []propsPackageReferenceEntry `xml:"PackageReference"` - VersionPackages []propsPackageVersionEntry `xml:"PackageVersion"` + ReferencePackages []propsPackageEntry `xml:"PackageReference"` + VersionPackages []propsPackageEntry `xml:"PackageVersion"` } type propsProject struct { From 2f339bbecf3933284b7bc9cd4a262dc4d152f6b3 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Sun, 5 Nov 2023 15:26:00 -0500 Subject: [PATCH 07/27] refactoring names --- pkg/nuget/packagesprops/parse.go | 12 ++++++------ pkg/nuget/packagesprops/parse_test.go | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 5e6b0ee9..37205044 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -1,4 +1,4 @@ -package config +package packagesprops import ( "encoding/xml" @@ -17,9 +17,9 @@ type propsPackageEntry struct { } type propsItemGroup struct { - xml.Name `xml:"ItemGroup"` - ReferencePackages []propsPackageEntry `xml:"PackageReference"` - VersionPackages []propsPackageEntry `xml:"PackageVersion"` + xml.Name `xml:"ItemGroup"` + PackageReferenceEntry []propsPackageEntry `xml:"PackageReference"` + PackageVersionEntry []propsPackageEntry `xml:"PackageVersion"` } type propsProject struct { @@ -55,7 +55,7 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, libs := make([]types.Library, 0) for _, itemGroup := range configData.ItemGroups { - for _, refPkg := range itemGroup.ReferencePackages { + for _, refPkg := range itemGroup.PackageReferenceEntry { var pkg = propsPackageEntry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} var lib = parsePackage(pkg) if len(lib.Name) > 0 && len(lib.Version) > 0 { @@ -63,7 +63,7 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, } } - for _, verPkg := range itemGroup.VersionPackages { + for _, verPkg := range itemGroup.PackageVersionEntry { var pkg = propsPackageEntry{verPkg.Version, verPkg.UpdatePackageName, verPkg.IncludePackageName} var lib = parsePackage(pkg) if len(lib.Name) > 0 && len(lib.Version) > 0 { diff --git a/pkg/nuget/packagesprops/parse_test.go b/pkg/nuget/packagesprops/parse_test.go index b7a00e3c..5b38db82 100644 --- a/pkg/nuget/packagesprops/parse_test.go +++ b/pkg/nuget/packagesprops/parse_test.go @@ -1,4 +1,4 @@ -package config_test +package packagesprops_test import ( "os" From 005ea2b2947807bb164079ec0f183d8f9fda07e4 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Sun, 5 Nov 2023 15:33:42 -0500 Subject: [PATCH 08/27] Adding test for severl item groups --- pkg/nuget/packagesprops/parse.go | 1 + pkg/nuget/packagesprops/parse_test.go | 9 +++++++++ pkg/nuget/packagesprops/testdata/SeveralItemGroups | 10 ++++++++++ 3 files changed, 20 insertions(+) create mode 100644 pkg/nuget/packagesprops/testdata/SeveralItemGroups diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 37205044..993edb2f 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -52,6 +52,7 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, } // https://github.com/dotnet/roslyn-tools/blob/8617f451b13e3dc29751cc78109f32ec73eeedb0/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L488 // Based on this documentation both legacy packages.props and Directory.packages.props are supported + // Directory.packages.props example: https://github.com/NuGet/Home/wiki/Centrally-managing-NuGet-package-versions libs := make([]types.Library, 0) for _, itemGroup := range configData.ItemGroups { diff --git a/pkg/nuget/packagesprops/parse_test.go b/pkg/nuget/packagesprops/parse_test.go index 5b38db82..1fee8abe 100644 --- a/pkg/nuget/packagesprops/parse_test.go +++ b/pkg/nuget/packagesprops/parse_test.go @@ -36,6 +36,15 @@ func TestParse(t *testing.T) { {Name: "PackageThree", Version: "2.4.1", ID: "PackageThree@2.4.1"}, }, }, + { + name: "SeveralItemGroupElements", + inputFile: "testdata/SeveralItemGroups", + want: []types.Library{ + {Name: "PackageOne", Version: "6.2.3", ID: "PackageOne@6.2.3"}, + {Name: "PackageTwo", Version: "6.0.0", ID: "PackageTwo@6.0.0"}, + {Name: "PackageThree", Version: "2.4.1", ID: "PackageThree@2.4.1"}, + }, + }, { name: "NoItemGroupInXMLStructure", inputFile: "testdata/no_item_group.props", diff --git a/pkg/nuget/packagesprops/testdata/SeveralItemGroups b/pkg/nuget/packagesprops/testdata/SeveralItemGroups new file mode 100644 index 00000000..1575af4a --- /dev/null +++ b/pkg/nuget/packagesprops/testdata/SeveralItemGroups @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file From f1fbf127c248f12fffbaab9c2f7215be059ec8b2 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Sun, 5 Nov 2023 15:44:54 -0500 Subject: [PATCH 09/27] removing code duplication --- pkg/nuget/packagesprops/parse.go | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 993edb2f..4ed556a4 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -10,7 +10,7 @@ import ( "github.com/aquasecurity/go-dep-parser/pkg/utils" ) -type propsPackageEntry struct { +type entry struct { Version string `xml:"Version,attr"` UpdatePackageName string `xml:"Update,attr"` IncludePackageName string `xml:"Include,attr"` @@ -18,8 +18,8 @@ type propsPackageEntry struct { type propsItemGroup struct { xml.Name `xml:"ItemGroup"` - PackageReferenceEntry []propsPackageEntry `xml:"PackageReference"` - PackageVersionEntry []propsPackageEntry `xml:"PackageVersion"` + PackageReferenceEntry []entry `xml:"PackageReference"` + PackageVersionEntry []entry `xml:"PackageVersion"` } type propsProject struct { @@ -32,7 +32,7 @@ func NewParser() types.Parser { return &Parser{} } -func parsePackage(pkg propsPackageEntry) types.Library { +func parsePackage(pkg entry) types.Library { // Update attribute is considered legacy, so preferring Include name := pkg.UpdatePackageName if pkg.IncludePackageName != "" { @@ -56,16 +56,8 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, libs := make([]types.Library, 0) for _, itemGroup := range configData.ItemGroups { - for _, refPkg := range itemGroup.PackageReferenceEntry { - var pkg = propsPackageEntry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} - var lib = parsePackage(pkg) - if len(lib.Name) > 0 && len(lib.Version) > 0 { - libs = append(libs, lib) - } - } - - for _, verPkg := range itemGroup.PackageVersionEntry { - var pkg = propsPackageEntry{verPkg.Version, verPkg.UpdatePackageName, verPkg.IncludePackageName} + for _, refPkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { + var pkg = entry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} var lib = parsePackage(pkg) if len(lib.Name) > 0 && len(lib.Version) > 0 { libs = append(libs, lib) From 4b877ff9d60232d72cf284f7069e22c375638fe9 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Sun, 5 Nov 2023 16:44:57 -0500 Subject: [PATCH 10/27] Adding checks for variable package name and version --- pkg/nuget/packagesprops/parse.go | 21 +++++++++++++++++-- pkg/nuget/packagesprops/parse_test.go | 9 +++++++- ...{SeveralItemGroups => several_item_groups} | 0 .../testdata/variables_and_empty | 9 ++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) rename pkg/nuget/packagesprops/testdata/{SeveralItemGroups => several_item_groups} (100%) create mode 100644 pkg/nuget/packagesprops/testdata/variables_and_empty diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 4ed556a4..c5d671b1 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -2,6 +2,7 @@ package packagesprops import ( "encoding/xml" + "strings" "golang.org/x/xerrors" @@ -45,12 +46,28 @@ func parsePackage(pkg entry) types.Library { } } +func isNonEmptyNonVariableLib(lib types.Library) bool { + if len(lib.Name) == 0 || len(lib.Version) == 0 { + return false + } + if isVariable(lib.Name) || isVariable(lib.Version) { + return false + } + return true + +} + +func isVariable(s string) bool { + trimmed := strings.Trim(s, " ") + return strings.HasPrefix(trimmed, "$(") && strings.HasSuffix(trimmed, ")") +} + func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, error) { var configData propsProject if err := xml.NewDecoder(r).Decode(&configData); err != nil { return nil, nil, xerrors.Errorf("failed to decode '*.packages.props' file: %w", err) } - // https://github.com/dotnet/roslyn-tools/blob/8617f451b13e3dc29751cc78109f32ec73eeedb0/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L488 + // https://github.com/dotnet/roslyn-tools/blob/b4c5220f5dfc4278847b6d38eff91cc1188f8066/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L150 // Based on this documentation both legacy packages.props and Directory.packages.props are supported // Directory.packages.props example: https://github.com/NuGet/Home/wiki/Centrally-managing-NuGet-package-versions @@ -59,7 +76,7 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, for _, refPkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { var pkg = entry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} var lib = parsePackage(pkg) - if len(lib.Name) > 0 && len(lib.Version) > 0 { + if isNonEmptyNonVariableLib(lib) { libs = append(libs, lib) } } diff --git a/pkg/nuget/packagesprops/parse_test.go b/pkg/nuget/packagesprops/parse_test.go index 1fee8abe..560328e3 100644 --- a/pkg/nuget/packagesprops/parse_test.go +++ b/pkg/nuget/packagesprops/parse_test.go @@ -38,13 +38,20 @@ func TestParse(t *testing.T) { }, { name: "SeveralItemGroupElements", - inputFile: "testdata/SeveralItemGroups", + inputFile: "testdata/several_item_groups", want: []types.Library{ {Name: "PackageOne", Version: "6.2.3", ID: "PackageOne@6.2.3"}, {Name: "PackageTwo", Version: "6.0.0", ID: "PackageTwo@6.0.0"}, {Name: "PackageThree", Version: "2.4.1", ID: "PackageThree@2.4.1"}, }, }, + { + name: "VariablesAsNamesOrVersion", + inputFile: "testdata/variables_and_empty", + want: []types.Library{ + {Name: "PackageFour", Version: "2.4.1", ID: "PackageFour@2.4.1"}, + }, + }, { name: "NoItemGroupInXMLStructure", inputFile: "testdata/no_item_group.props", diff --git a/pkg/nuget/packagesprops/testdata/SeveralItemGroups b/pkg/nuget/packagesprops/testdata/several_item_groups similarity index 100% rename from pkg/nuget/packagesprops/testdata/SeveralItemGroups rename to pkg/nuget/packagesprops/testdata/several_item_groups diff --git a/pkg/nuget/packagesprops/testdata/variables_and_empty b/pkg/nuget/packagesprops/testdata/variables_and_empty new file mode 100644 index 00000000..d801b1f7 --- /dev/null +++ b/pkg/nuget/packagesprops/testdata/variables_and_empty @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file From d981da72a30cb9f3fa2f1e4f51811c627e15765f Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Thu, 9 Nov 2023 20:33:11 -0500 Subject: [PATCH 11/27] better names --- pkg/nuget/packagesprops/parse.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index c5d671b1..0a822aaf 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -17,14 +17,13 @@ type entry struct { IncludePackageName string `xml:"Include,attr"` } -type propsItemGroup struct { - xml.Name `xml:"ItemGroup"` +type itemGroup struct { PackageReferenceEntry []entry `xml:"PackageReference"` PackageVersionEntry []entry `xml:"PackageVersion"` } -type propsProject struct { - ItemGroups []propsItemGroup `xml:"ItemGroup"` +type project struct { + ItemGroups []itemGroup `xml:"ItemGroup"` } type Parser struct{} @@ -63,7 +62,7 @@ func isVariable(s string) bool { } func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, error) { - var configData propsProject + var configData project if err := xml.NewDecoder(r).Decode(&configData); err != nil { return nil, nil, xerrors.Errorf("failed to decode '*.packages.props' file: %w", err) } From d1bfb1e95ed0b16042cdb3a0e253e6ed50952d5d Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Thu, 9 Nov 2023 20:48:42 -0500 Subject: [PATCH 12/27] trimming version and package name --- pkg/nuget/packagesprops/parse.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 0a822aaf..afefcddb 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -34,18 +34,19 @@ func NewParser() types.Parser { func parsePackage(pkg entry) types.Library { // Update attribute is considered legacy, so preferring Include - name := pkg.UpdatePackageName + name := strings.Trim(pkg.UpdatePackageName, " ") if pkg.IncludePackageName != "" { - name = pkg.IncludePackageName + name = strings.Trim(pkg.IncludePackageName, " ") } + version := strings.Trim(pkg.Version, " ") return types.Library{ - ID: utils.PackageID(name, pkg.Version), + ID: utils.PackageID(name, version), Name: name, - Version: pkg.Version, + Version: version, } } -func isNonEmptyNonVariableLib(lib types.Library) bool { +func shouldSkipLib(lib types.Library) bool { if len(lib.Name) == 0 || len(lib.Version) == 0 { return false } @@ -75,7 +76,7 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, for _, refPkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { var pkg = entry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} var lib = parsePackage(pkg) - if isNonEmptyNonVariableLib(lib) { + if shouldSkipLib(lib) { libs = append(libs, lib) } } From ede0db353520d20376a0ec276cd80154a852f37c Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Thu, 9 Nov 2023 20:50:52 -0500 Subject: [PATCH 13/27] adding comments --- pkg/nuget/packagesprops/parse.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index afefcddb..3a6e9502 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -50,6 +50,8 @@ func shouldSkipLib(lib types.Library) bool { if len(lib.Name) == 0 || len(lib.Version) == 0 { return false } + // *packages.props files don't contain variable resolution information. + // So we need to skip them. if isVariable(lib.Name) || isVariable(lib.Version) { return false } From 357b23a35bd699c0d7b380609c604c3fd52504b8 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Thu, 9 Nov 2023 20:52:55 -0500 Subject: [PATCH 14/27] removing var --- pkg/nuget/packagesprops/parse.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 3a6e9502..27f7fc64 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -76,8 +76,8 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, libs := make([]types.Library, 0) for _, itemGroup := range configData.ItemGroups { for _, refPkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { - var pkg = entry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} - var lib = parsePackage(pkg) + pkg := entry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} + lib := parsePackage(pkg) if shouldSkipLib(lib) { libs = append(libs, lib) } From 138e4c6541a35c5d8d6ed902fc352d6108f10137 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Thu, 9 Nov 2023 21:06:04 -0500 Subject: [PATCH 15/27] removing unnecessary struct --- pkg/nuget/packagesprops/parse.go | 7 +++---- pkg/nuget/packagesprops/testdata/Directory.Packages.props | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 27f7fc64..46058f1a 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -32,7 +32,7 @@ func NewParser() types.Parser { return &Parser{} } -func parsePackage(pkg entry) types.Library { +func library(pkg entry) types.Library { // Update attribute is considered legacy, so preferring Include name := strings.Trim(pkg.UpdatePackageName, " ") if pkg.IncludePackageName != "" { @@ -75,9 +75,8 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, libs := make([]types.Library, 0) for _, itemGroup := range configData.ItemGroups { - for _, refPkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { - pkg := entry{refPkg.Version, refPkg.UpdatePackageName, refPkg.IncludePackageName} - lib := parsePackage(pkg) + for _, pkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { + lib := library(pkg) if shouldSkipLib(lib) { libs = append(libs, lib) } diff --git a/pkg/nuget/packagesprops/testdata/Directory.Packages.props b/pkg/nuget/packagesprops/testdata/Directory.Packages.props index 0f39c0a2..62c085ba 100644 --- a/pkg/nuget/packagesprops/testdata/Directory.Packages.props +++ b/pkg/nuget/packagesprops/testdata/Directory.Packages.props @@ -1,7 +1,7 @@ - + - + \ No newline at end of file From 9d5087bf5034541f3ca425104194208f950ca149 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Thu, 9 Nov 2023 21:10:57 -0500 Subject: [PATCH 16/27] refactoring: better names --- pkg/nuget/packagesprops/parse.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 46058f1a..4916d8e2 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -11,15 +11,15 @@ import ( "github.com/aquasecurity/go-dep-parser/pkg/utils" ) -type entry struct { +type pkg struct { Version string `xml:"Version,attr"` UpdatePackageName string `xml:"Update,attr"` IncludePackageName string `xml:"Include,attr"` } type itemGroup struct { - PackageReferenceEntry []entry `xml:"PackageReference"` - PackageVersionEntry []entry `xml:"PackageVersion"` + PackageReferenceEntry []pkg `xml:"PackageReference"` + PackageVersionEntry []pkg `xml:"PackageVersion"` } type project struct { @@ -32,13 +32,13 @@ func NewParser() types.Parser { return &Parser{} } -func library(pkg entry) types.Library { +func library(p pkg) types.Library { // Update attribute is considered legacy, so preferring Include - name := strings.Trim(pkg.UpdatePackageName, " ") - if pkg.IncludePackageName != "" { - name = strings.Trim(pkg.IncludePackageName, " ") + name := strings.Trim(p.UpdatePackageName, " ") + if p.IncludePackageName != "" { + name = strings.Trim(p.IncludePackageName, " ") } - version := strings.Trim(pkg.Version, " ") + version := strings.Trim(p.Version, " ") return types.Library{ ID: utils.PackageID(name, version), Name: name, From 6733ffbb459bf4d915942e99c3abb29313bd478f Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Fri, 10 Nov 2023 09:55:57 -0500 Subject: [PATCH 17/27] project element has to be a part of props xml --- pkg/nuget/packagesprops/parse.go | 1 + pkg/nuget/packagesprops/parse_test.go | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 4916d8e2..e72b6aac 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -23,6 +23,7 @@ type itemGroup struct { } type project struct { + XMLName xml.Name `xml:"Project"` ItemGroups []itemGroup `xml:"ItemGroup"` } diff --git a/pkg/nuget/packagesprops/parse_test.go b/pkg/nuget/packagesprops/parse_test.go index 560328e3..298dfac9 100644 --- a/pkg/nuget/packagesprops/parse_test.go +++ b/pkg/nuget/packagesprops/parse_test.go @@ -57,6 +57,11 @@ func TestParse(t *testing.T) { inputFile: "testdata/no_item_group.props", want: []types.Library{}, }, + { + name: "NoProject", + inputFile: "testdata/no_project.props", + wantErr: "failed to decode '*.packages.props' file", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 7e0925d81b853c5c66b0e5186eeb410ff5874f33 Mon Sep 17 00:00:00 2001 From: yuriShafet <5830215+yuriShafet@users.noreply.github.com> Date: Fri, 10 Nov 2023 19:24:15 -0500 Subject: [PATCH 18/27] more comments Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> --- pkg/nuget/packagesprops/parse.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index e72b6aac..f7a8a389 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -17,6 +17,7 @@ type pkg struct { IncludePackageName string `xml:"Include,attr"` } +// https://github.com/dotnet/roslyn-tools/blob/b4c5220f5dfc4278847b6d38eff91cc1188f8066/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L150 type itemGroup struct { PackageReferenceEntry []pkg `xml:"PackageReference"` PackageVersionEntry []pkg `xml:"PackageVersion"` From 9d20f1c18a85c9a7812fc902f9c05695c677d3cd Mon Sep 17 00:00:00 2001 From: yuriShafet <5830215+yuriShafet@users.noreply.github.com> Date: Fri, 10 Nov 2023 19:25:51 -0500 Subject: [PATCH 19/27] refactoring Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> --- pkg/nuget/packagesprops/parse.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index f7a8a389..08901b76 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -34,13 +34,15 @@ func NewParser() types.Parser { return &Parser{} } -func library(p pkg) types.Library { +func (p pkg) library() types.Library { // Update attribute is considered legacy, so preferring Include - name := strings.Trim(p.UpdatePackageName, " ") + name := p.UpdatePackageName if p.IncludePackageName != "" { - name = strings.Trim(p.IncludePackageName, " ") + name = p.IncludePackageName } - version := strings.Trim(p.Version, " ") + + name = strings.TrimSpace(name) + version := strings.TrimSpace(p.Version) return types.Library{ ID: utils.PackageID(name, version), Name: name, From 4f0a3bd7512291c65728fa9868a3a3ea52c8306e Mon Sep 17 00:00:00 2001 From: yuriShafet <5830215+yuriShafet@users.noreply.github.com> Date: Fri, 10 Nov 2023 19:28:02 -0500 Subject: [PATCH 20/27] more refactoring Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> --- pkg/nuget/packagesprops/parse.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 08901b76..bbb799d7 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -52,14 +52,15 @@ func (p pkg) library() types.Library { func shouldSkipLib(lib types.Library) bool { if len(lib.Name) == 0 || len(lib.Version) == 0 { - return false + return true } // *packages.props files don't contain variable resolution information. // So we need to skip them. if isVariable(lib.Name) || isVariable(lib.Version) { - return false + return true } - return true + return false +} } From d551848ec7600e6e3ffc863d1a3fac01ac7d6c39 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Fri, 10 Nov 2023 19:34:07 -0500 Subject: [PATCH 21/27] moving comment --- pkg/nuget/packagesprops/parse.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 08901b76..3243be11 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -18,6 +18,8 @@ type pkg struct { } // https://github.com/dotnet/roslyn-tools/blob/b4c5220f5dfc4278847b6d38eff91cc1188f8066/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L150 +// Based on this documentation both legacy packages.props and Directory.packages.props are supported +// Directory.packages.props example: https://github.com/NuGet/Home/wiki/Centrally-managing-NuGet-package-versions type itemGroup struct { PackageReferenceEntry []pkg `xml:"PackageReference"` PackageVersionEntry []pkg `xml:"PackageVersion"` @@ -73,14 +75,11 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, if err := xml.NewDecoder(r).Decode(&configData); err != nil { return nil, nil, xerrors.Errorf("failed to decode '*.packages.props' file: %w", err) } - // https://github.com/dotnet/roslyn-tools/blob/b4c5220f5dfc4278847b6d38eff91cc1188f8066/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L150 - // Based on this documentation both legacy packages.props and Directory.packages.props are supported - // Directory.packages.props example: https://github.com/NuGet/Home/wiki/Centrally-managing-NuGet-package-versions libs := make([]types.Library, 0) for _, itemGroup := range configData.ItemGroups { for _, pkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { - lib := library(pkg) + lib := pkg.library() if shouldSkipLib(lib) { libs = append(libs, lib) } From 47f383e22ce062404c29ef975e4f24ed395f5801 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Fri, 10 Nov 2023 19:36:36 -0500 Subject: [PATCH 22/27] resolving conflict --- pkg/nuget/packagesprops/parse.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index af63aaf2..6cefbe10 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -64,8 +64,6 @@ func shouldSkipLib(lib types.Library) bool { return false } -} - func isVariable(s string) bool { trimmed := strings.Trim(s, " ") return strings.HasPrefix(trimmed, "$(") && strings.HasSuffix(trimmed, ")") @@ -81,7 +79,7 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, for _, itemGroup := range configData.ItemGroups { for _, pkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { lib := pkg.library() - if shouldSkipLib(lib) { + if !shouldSkipLib(lib) { libs = append(libs, lib) } } From c172b931b932ebd9f09415ff362bc06029f3e085 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Fri, 10 Nov 2023 19:37:47 -0500 Subject: [PATCH 23/27] better naming --- pkg/nuget/packagesprops/parse.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index 6cefbe10..c85c518e 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -76,8 +76,8 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, } libs := make([]types.Library, 0) - for _, itemGroup := range configData.ItemGroups { - for _, pkg := range append(itemGroup.PackageReferenceEntry, itemGroup.PackageVersionEntry...) { + for _, item := range configData.ItemGroups { + for _, pkg := range append(item.PackageReferenceEntry, item.PackageVersionEntry...) { lib := pkg.library() if !shouldSkipLib(lib) { libs = append(libs, lib) From 2321d8cf686c5305e522b151d8b914fe1da569d6 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Fri, 10 Nov 2023 19:40:32 -0500 Subject: [PATCH 24/27] removing unnecessary Trim calls --- pkg/nuget/packagesprops/parse.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index c85c518e..ccec9353 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -65,8 +65,7 @@ func shouldSkipLib(lib types.Library) bool { } func isVariable(s string) bool { - trimmed := strings.Trim(s, " ") - return strings.HasPrefix(trimmed, "$(") && strings.HasSuffix(trimmed, ")") + return strings.HasPrefix(s, "$(") && strings.HasSuffix(s, ")") } func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, error) { From 5288d1cfabc2fc0a4544c1018f8d577c78ab2991 Mon Sep 17 00:00:00 2001 From: yuriShafet <5830215+yuriShafet@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:31:40 -0500 Subject: [PATCH 25/27] Updating comments Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> --- pkg/nuget/packagesprops/parse.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index ccec9353..e67a3b02 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -18,8 +18,6 @@ type pkg struct { } // https://github.com/dotnet/roslyn-tools/blob/b4c5220f5dfc4278847b6d38eff91cc1188f8066/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L150 -// Based on this documentation both legacy packages.props and Directory.packages.props are supported -// Directory.packages.props example: https://github.com/NuGet/Home/wiki/Centrally-managing-NuGet-package-versions type itemGroup struct { PackageReferenceEntry []pkg `xml:"PackageReference"` PackageVersionEntry []pkg `xml:"PackageVersion"` From 0d91a1daac9bed2a8402434a04428580db1ae188 Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Tue, 14 Nov 2023 15:36:30 -0500 Subject: [PATCH 26/27] refactoring libs initialization --- pkg/nuget/packagesprops/parse.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/nuget/packagesprops/parse.go b/pkg/nuget/packagesprops/parse.go index e67a3b02..995364a6 100644 --- a/pkg/nuget/packagesprops/parse.go +++ b/pkg/nuget/packagesprops/parse.go @@ -72,7 +72,7 @@ func (p *Parser) Parse(r dio.ReadSeekerAt) ([]types.Library, []types.Dependency, return nil, nil, xerrors.Errorf("failed to decode '*.packages.props' file: %w", err) } - libs := make([]types.Library, 0) + var libs []types.Library for _, item := range configData.ItemGroups { for _, pkg := range append(item.PackageReferenceEntry, item.PackageVersionEntry...) { lib := pkg.library() From 08b9d5ce0e661363fba8098515207c9fb61ee57d Mon Sep 17 00:00:00 2001 From: YuriShafet Date: Tue, 14 Nov 2023 15:50:20 -0500 Subject: [PATCH 27/27] fixing unit tests --- pkg/nuget/packagesprops/parse_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/nuget/packagesprops/parse_test.go b/pkg/nuget/packagesprops/parse_test.go index 298dfac9..56318f74 100644 --- a/pkg/nuget/packagesprops/parse_test.go +++ b/pkg/nuget/packagesprops/parse_test.go @@ -32,8 +32,8 @@ func TestParse(t *testing.T) { inputFile: "testdata/Directory.Packages.props", want: []types.Library{ {Name: "PackageOne", Version: "6.2.3", ID: "PackageOne@6.2.3"}, - {Name: "PackageTwo", Version: "6.0.0", ID: "PackageTwo@6.0.0"}, {Name: "PackageThree", Version: "2.4.1", ID: "PackageThree@2.4.1"}, + {Name: "PackageTwo", Version: "6.0.0", ID: "PackageTwo@6.0.0"}, }, }, { @@ -41,8 +41,8 @@ func TestParse(t *testing.T) { inputFile: "testdata/several_item_groups", want: []types.Library{ {Name: "PackageOne", Version: "6.2.3", ID: "PackageOne@6.2.3"}, - {Name: "PackageTwo", Version: "6.0.0", ID: "PackageTwo@6.0.0"}, {Name: "PackageThree", Version: "2.4.1", ID: "PackageThree@2.4.1"}, + {Name: "PackageTwo", Version: "6.0.0", ID: "PackageTwo@6.0.0"}, }, }, { @@ -55,7 +55,7 @@ func TestParse(t *testing.T) { { name: "NoItemGroupInXMLStructure", inputFile: "testdata/no_item_group.props", - want: []types.Library{}, + want: []types.Library(nil), }, { name: "NoProject", @@ -76,7 +76,7 @@ func TestParse(t *testing.T) { } assert.NoError(t, err) - assert.ElementsMatch(t, tt.want, got) + assert.Equal(t, tt.want, got) }) } }