Skip to content

Commit

Permalink
feature: add weak-compatible to dependency check (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
Two-Hearts committed Nov 1, 2023
1 parent 45c9d9c commit a790ab8
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 17 deletions.
19 changes: 19 additions & 0 deletions assets/compatibility/Apache-2.0.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,22 @@ incompatible:
- CPOL-1.02
- NPL-1.0
- NPL-1.1

weak-compatible:
- CDDL-1.0
- CDDL-1.1
- CPL-1.0
- EPL-1.0
- EPL-2.0
- ErlPL-1.1
- IPA
- IPL-1.0
- LicenseRef-scancode-ubuntu-font-1.0
- LicenseRef-scancode-unrar
- MPL-1.0
- MPL-1.1
- MPL-2.0
- OFL-1.1
- OSL-3.0
- Ruby
- SPL-1.0
11 changes: 10 additions & 1 deletion commands/deps_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ import (
"github.com/apache/skywalking-eyes/pkg/deps"
)

var weakCompatible bool

func init() {
DepsCheckCommand.PersistentFlags().BoolVarP(&weakCompatible, "weak-compatible", "w", false,
"if set to true, treat the weak-compatible licenses as compatible in dependencies check. "+
"Note: when set to true, make sure to manually confirm that weak-compatible licenses "+
"are used under the required conditions.")
}

var DepsCheckCommand = &cobra.Command{
Use: "check",
Aliases: []string{"c"},
Expand All @@ -34,7 +43,7 @@ var DepsCheckCommand = &cobra.Command{
var errors []error
configDeps := Config.Dependencies()
for _, header := range Config.Headers() {
if err := deps.Check(header.License.SpdxID, configDeps); err != nil {
if err := deps.Check(header.License.SpdxID, configDeps, weakCompatible); err != nil {
errors = append(errors, err)
}
}
Expand Down
26 changes: 18 additions & 8 deletions pkg/deps/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ import (
)

type CompatibilityMatrix struct {
Compatible []string `yaml:"compatible"`
Incompatible []string `yaml:"incompatible"`
Compatible []string `yaml:"compatible"`
Incompatible []string `yaml:"incompatible"`
WeakCompatible []string `yaml:"weak-compatible"`
}

var matrices = make(map[string]CompatibilityMatrix)
Expand Down Expand Up @@ -63,15 +64,15 @@ func init() {
}
}

func Check(mainLicenseSpdxID string, config *ConfigDeps) error {
func Check(mainLicenseSpdxID string, config *ConfigDeps, weakCompatible bool) error {
matrix := matrices[mainLicenseSpdxID]

report := Report{}
if err := Resolve(config, &report); err != nil {
return nil
}

return CheckWithMatrix(mainLicenseSpdxID, &matrix, &report)
return CheckWithMatrix(mainLicenseSpdxID, &matrix, &report, weakCompatible)
}

func compare(list []string, spdxID string) bool {
Expand Down Expand Up @@ -99,16 +100,22 @@ func compareAny(spdxIDs []string, compare func(spdxID string) bool) bool {
return false
}

func CheckWithMatrix(mainLicenseSpdxID string, matrix *CompatibilityMatrix, report *Report) error {
func compareCompatible(matrix *CompatibilityMatrix, spdxID string, weakCompatible bool) bool {
if weakCompatible {
return compare(matrix.Compatible, spdxID) || compare(matrix.WeakCompatible, spdxID)
}
return compare(matrix.Compatible, spdxID)
}

func CheckWithMatrix(mainLicenseSpdxID string, matrix *CompatibilityMatrix, report *Report, weakCompatible bool) error {
var incompatibleResults []*Result
var unknownResults []*Result
for _, result := range append(report.Resolved, report.Skipped...) {
operator, spdxIDs := parseLicenseExpression(result.LicenseSpdxID)

switch operator {
case LicenseOperatorAND:
if compareAll(spdxIDs, func(spdxID string) bool {
return compare(matrix.Compatible, spdxID)
return compareCompatible(matrix, spdxID, weakCompatible)
}) {
continue
}
Expand All @@ -120,7 +127,7 @@ func CheckWithMatrix(mainLicenseSpdxID string, matrix *CompatibilityMatrix, repo

case LicenseOperatorOR:
if compareAny(spdxIDs, func(spdxID string) bool {
return compare(matrix.Compatible, spdxID)
return compareCompatible(matrix, spdxID, weakCompatible)
}) {
continue
}
Expand All @@ -134,6 +141,9 @@ func CheckWithMatrix(mainLicenseSpdxID string, matrix *CompatibilityMatrix, repo
if compatible := compare(matrix.Compatible, spdxIDs[0]); compatible {
continue
}
if weakCompatible && compare(matrix.WeakCompatible, spdxIDs[0]) {
continue
}
if incompatible := compare(matrix.Incompatible, spdxIDs[0]); incompatible {
incompatibleResults = append(incompatibleResults, result)
continue
Expand Down
42 changes: 34 additions & 8 deletions pkg/deps/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
package deps_test

import (
"github.com/apache/skywalking-eyes/pkg/deps"
"strings"
"testing"

"github.com/apache/skywalking-eyes/pkg/deps"
)

var TestMatrix = deps.CompatibilityMatrix{
Expand Down Expand Up @@ -52,6 +53,9 @@ var TestMatrix = deps.CompatibilityMatrix{
"GPL-2.0-only",
"GPL-2.0-or-later",
},
WeakCompatible: []string{
"MPL-2.0",
},
}

func TestCheckWithMatrix(t *testing.T) {
Expand All @@ -62,7 +66,7 @@ func TestCheckWithMatrix(t *testing.T) {
LicenseSpdxID: "Apache-2.0",
},
},
}); err != nil {
}, false); err != nil {
t.Errorf("Shouldn't return error")
}

Expand All @@ -77,7 +81,7 @@ func TestCheckWithMatrix(t *testing.T) {
LicenseSpdxID: "LGPL-2.0",
},
},
}); err == nil {
}, false); err == nil {
t.Errorf("Should return error")
} else if !strings.Contains(err.Error(), "Bar | LGPL-2.0") {
t.Errorf("Should return error and contains dependency Bar, now is `%s`", err.Error())
Expand All @@ -96,7 +100,7 @@ func TestCheckWithMatrix(t *testing.T) {
LicenseSpdxID: "Unknown",
},
},
}); err == nil {
}, false); err == nil {
t.Errorf("Should return error")
} else if !strings.Contains(err.Error(), "Bar | Unknown") {
t.Errorf("Should return error and has dependency Bar, now is `%s`", err.Error())
Expand All @@ -109,7 +113,7 @@ func TestCheckWithMatrix(t *testing.T) {
LicenseSpdxID: "Apache-2.0 OR MIT",
},
},
}); err != nil {
}, false); err != nil {
t.Errorf("Shouldn't return error")
}

Expand All @@ -120,7 +124,7 @@ func TestCheckWithMatrix(t *testing.T) {
LicenseSpdxID: "GPL-3.0 and GPL-3.0-or-later",
},
},
}); err == nil {
}, false); err == nil {
t.Errorf("Should return error")
}

Expand All @@ -131,7 +135,7 @@ func TestCheckWithMatrix(t *testing.T) {
LicenseSpdxID: "LGPL-2.1-only AND MIT AND BSD-2-Clause",
},
},
}); err == nil {
}, false); err == nil {
t.Errorf("Should return error")
}

Expand All @@ -142,7 +146,29 @@ func TestCheckWithMatrix(t *testing.T) {
LicenseSpdxID: "GPL-2.0-or-later WITH Bison-exception-2.2",
},
},
}); err == nil {
}, false); err == nil {
t.Errorf("Should return error")
}

if err := deps.CheckWithMatrix("Apache-2.0", &TestMatrix, &deps.Report{
Resolved: []*deps.Result{
{
Dependency: "Foo",
LicenseSpdxID: "MPL-2.0",
},
},
}, false); err == nil {
t.Errorf("Should return error since weak-compatible is turned off")
}

if err := deps.CheckWithMatrix("Apache-2.0", &TestMatrix, &deps.Report{
Resolved: []*deps.Result{
{
Dependency: "Bar",
LicenseSpdxID: "MPL-2.0",
},
},
}, true); err != nil {
t.Errorf("Shouldn't return error")
}
}

0 comments on commit a790ab8

Please sign in to comment.