@@ -1201,37 +1201,21 @@ func LibraryPropertiesDependsFieldNotInIndex() (result ruleresult.Type, output s
12011201 return ruleresult .Skip , "Field not present"
12021202 }
12031203
1204- dependsList := commaSeparatedToList (depends )
1204+ dependencies := libDependencies (depends )
12051205
1206- var dependencyRegexp = regexp .MustCompile ("^([^()]+?) *(?:\\ ((.+)\\ ))?$" )
12071206 dependsNotInIndex := []string {}
1208- for _ , depend := range dependsList {
1209- // Process raw depend string into a dependency object
1210- if depend == "" {
1211- // This is the responsibility of LibraryPropertiesDependsFieldInvalidFormat()
1212- continue
1213- }
1214- dependencyData := dependencyRegexp .FindAllStringSubmatch (depend , - 1 )
1215- if dependencyData == nil {
1216- // This is the responsibility of LibraryPropertiesDependsFieldInvalidFormat()
1217- continue
1218- }
1219- dependencyConstraint , err := semver .ParseConstraint (dependencyData [0 ][2 ])
1220- if err != nil {
1207+ for _ , dependency := range dependencies {
1208+ if dependency .parseConstraintErr != nil {
12211209 // This is the responsibility of LibraryPropertiesDependsFieldInvalidFormat()
12221210 continue
12231211 }
1224- var dependency semver.Dependency = & librariesindex.Dependency {
1225- Name : dependencyData [0 ][1 ],
1226- VersionConstraint : dependencyConstraint ,
1227- }
12281212
1229- logrus .Tracef ("Checking if dependency %s is in index." , depend )
1213+ logrus .Tracef ("Checking if dependency %s is in index." , dependency . depend )
12301214 // Get all releases of the dependency
1231- library := projectdata .LibraryManagerIndex ().Index .FindIndexedLibrary (& libraries.Library {Name : dependency .GetName ()})
1215+ library := projectdata .LibraryManagerIndex ().Index .FindIndexedLibrary (& libraries.Library {Name : dependency .data . GetName ()})
12321216 if library == nil {
12331217 logrus .Tracef ("Dependency is not in the index." )
1234- dependsNotInIndex = append (dependsNotInIndex , depend )
1218+ dependsNotInIndex = append (dependsNotInIndex , dependency . depend )
12351219 continue
12361220 }
12371221 // Convert the dependency's libraries.Library object to a semver.Releases object
@@ -1240,10 +1224,10 @@ func LibraryPropertiesDependsFieldNotInIndex() (result ruleresult.Type, output s
12401224 releases = append (releases , release )
12411225 }
12421226 // Filter the dependency's releases according to the dependency's constraint
1243- dependencyReleases := releases .FilterBy (dependency )
1227+ dependencyReleases := releases .FilterBy (& dependency . data )
12441228 if len (dependencyReleases ) == 0 {
12451229 logrus .Tracef ("No releases match dependency's constraint." )
1246- dependsNotInIndex = append (dependsNotInIndex , depend )
1230+ dependsNotInIndex = append (dependsNotInIndex , dependency . depend )
12471231 continue
12481232 }
12491233 }
@@ -1255,6 +1239,34 @@ func LibraryPropertiesDependsFieldNotInIndex() (result ruleresult.Type, output s
12551239 return ruleresult .Pass , ""
12561240}
12571241
1242+ // LibraryPropertiesDependsFieldConstraintInvalid checks whether the syntax of the version constraints in the
1243+ // library.properties `depends` field is valid.
1244+ func LibraryPropertiesDependsFieldConstraintInvalid () (result ruleresult.Type , output string ) {
1245+ if projectdata .LibraryPropertiesLoadError () != nil {
1246+ return ruleresult .NotRun , "Couldn't load library.properties"
1247+ }
1248+
1249+ depends , hasDepends := projectdata .LibraryProperties ().GetOk ("depends" )
1250+ if ! hasDepends {
1251+ return ruleresult .Skip , "Field not present"
1252+ }
1253+
1254+ dependencies := libDependencies (depends )
1255+
1256+ nonCompliant := []string {}
1257+ for _ , dependency := range dependencies {
1258+ if dependency .parseConstraintErr != nil {
1259+ nonCompliant = append (nonCompliant , dependency .depend )
1260+ }
1261+ }
1262+
1263+ if len (nonCompliant ) > 0 {
1264+ return ruleresult .Fail , strings .Join (nonCompliant , ", " )
1265+ }
1266+
1267+ return ruleresult .Pass , ""
1268+ }
1269+
12581270// LibraryPropertiesDotALinkageFieldInvalid checks for invalid value in the library.properties "dot_a_linkage" field.
12591271func LibraryPropertiesDotALinkageFieldInvalid () (result ruleresult.Type , output string ) {
12601272 if projectdata .LibraryPropertiesLoadError () != nil {
@@ -1552,3 +1564,45 @@ func commaSeparatedToList(commaSeparated string) []string {
15521564
15531565 return list
15541566}
1567+
1568+ // libDependency is a library dependency
1569+ type libDependency struct {
1570+ depend string // Raw element from depends field.
1571+ data librariesindex.Dependency // Dependency object.
1572+ parseConstraintErr error // Error produced by parsing the version constraint.
1573+ }
1574+
1575+ var dependRegexp = regexp .MustCompile ("^([^()]+?) *(?:\\ ((.*)\\ ))?$" )
1576+
1577+ // libDependencies parses the library.properties `depends` field contents and returns an array of libDependency objects
1578+ func libDependencies (depends string ) []libDependency {
1579+ dependList := commaSeparatedToList (depends )
1580+
1581+ dependencies := []libDependency {}
1582+ for _ , depend := range dependList {
1583+ // Process raw depend string into a dependency object
1584+ if depend == "" {
1585+ // This function is only concerned with the parseable depend elements.
1586+ // `depends` field data format is checked separately.
1587+ continue
1588+ }
1589+ dependencyData := dependRegexp .FindAllStringSubmatch (depend , - 1 )
1590+ if dependencyData == nil {
1591+ // This function is only concerned with the parseable depend elements.
1592+ // `depends` field data format is checked separately.
1593+ continue
1594+ }
1595+ dependencyConstraint , err := semver .ParseConstraint (dependencyData [0 ][2 ])
1596+ dependencies = append (dependencies , libDependency {
1597+ depend : depend ,
1598+ data : librariesindex.Dependency {
1599+ Name : dependencyData [0 ][1 ],
1600+ VersionConstraint : dependencyConstraint ,
1601+ },
1602+ parseConstraintErr : err ,
1603+ },
1604+ )
1605+ }
1606+
1607+ return dependencies
1608+ }
0 commit comments