This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-eyes.git
The following commit(s) were added to refs/heads/main by this push:
new a63f4af Set up mechanism to check dependencies' license
compatibilities (#58)
a63f4af is described below
commit a63f4afcc287dfb3727ecc45a4afc55a5e69c15f
Author: kezhenxu94 <[email protected]>
AuthorDate: Wed Aug 18 21:56:04 2021 +0800
Set up mechanism to check dependencies' license compatibilities (#58)
---
README.md | 29 ++++++++++++
assets/compatibility/Apache-2.0.yaml | 92 ++++++++++++++++++++++++++++++++++++
commands/deps.go | 3 +-
commands/{deps.go => deps_check.go} | 18 +++----
commands/deps_resolve.go | 2 +-
pkg/deps/check.go | 90 +++++++++++++++++++++++++++++++++++
pkg/license/identifier_test.go | 70 +++++++++++++++++++++++++++
pkg/license/norm.go | 10 ++++
8 files changed, 303 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index 61dd4a0..effb082 100644
--- a/README.md
+++ b/README.md
@@ -95,6 +95,8 @@ INFO Totally checked 20 files, valid: 10, invalid: 10,
ignored: 0, fixed: 10
#### Resolve Dependencies' licenses
+This command serves as assistance for human beings to audit the dependencies
license, it's exit code is always 0.
+
```bash
$ bin/darwin/license-eye -c test/testdata/.licenserc_for_test_check.yaml dep
resolve
INFO GITHUB_TOKEN is not set, license-eye won't comment on the pull request
@@ -135,6 +137,33 @@ ERROR failed to identify the licenses of following
packages:
gopkg.in/yaml.v3
```
+#### Check Dependencies' licenses
+
+This command can be used to perform automatic license compatibility check,
when there is incompatible licenses found,
+the command will exit with status code 1 and fail the command.
+
+```bash
+$ bin/darwin/license-eye -c test/testdata/.licenserc_for_test_check.yaml dep
check
+INFO GITHUB_TOKEN is not set, license-eye won't comment on the pull request
+INFO Loading configuration from file: .licenserc.yaml
+WARNING Failed to resolve the license of <github.com/gogo/protobuf>: cannot
identify license content
+WARNING Failed to resolve the license of <github.com/kr/logfmt>: cannot find
license file
+WARNING Failed to resolve the license of <github.com/magiconair/properties>:
cannot identify license content
+WARNING Failed to resolve the license of <github.com/miekg/dns>: cannot
identify license content
+WARNING Failed to resolve the license of <github.com/pascaldekloe/goe>: cannot
identify license content
+WARNING Failed to resolve the license of <github.com/russross/blackfriday/v2>:
cannot identify license content
+WARNING Failed to resolve the license of <gopkg.in/check.v1>: cannot identify
license content
+ERROR the following licenses are incompatible with the main license:
Apache-2.0
+License: Unknown Dependency: github.com/gogo/protobuf
+License: Unknown Dependency: github.com/kr/logfmt
+License: Unknown Dependency: github.com/magiconair/properties
+License: Unknown Dependency: github.com/miekg/dns
+License: Unknown Dependency: github.com/pascaldekloe/goe
+License: Unknown Dependency: github.com/russross/blackfriday/v2
+License: Unknown Dependency: gopkg.in/check.v1
+exit status 1
+```
+
## Configurations
```yaml
diff --git a/assets/compatibility/Apache-2.0.yaml
b/assets/compatibility/Apache-2.0.yaml
new file mode 100644
index 0000000..44a8271
--- /dev/null
+++ b/assets/compatibility/Apache-2.0.yaml
@@ -0,0 +1,92 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# The compatibility is extracted from
https://www.apache.org/legal/resolved.html
+
+compatible:
+ - Apache-2.0
+ - PHP-3.01
+ - BSD-3-Clause
+ - BSD-2-Clause
+ - PostgreSQL
+ - EPL-1.0
+ - ISC
+ - SMLNJ
+ - ICU.txt
+ - NCSA.txt
+ - W3C.txt
+ - Xnet.txt
+ - Zlib.txt
+ - Libpng.txt
+ - AFL-3.0.txt
+ - MS-PL.txt
+ - PSF-2.0.txt
+ - BSL-1.0.txt
+ - WTFPL.txt
+ - Unicode-DFS-2016.txt
+ - Unicode-DFS-2015.txt
+ - ZPL-2.0.txt
+ - Unlicense.txt
+ - HPND.txt
+ - MulanPSL-2.0.txt
+
+incompatible:
+ - Unknown
+ - LGPL-2.0+
+ - LGPL-2.0
+ - LGPL-2.0-only
+ - LGPL-2.0-or-later
+ - LGPL-2.1+
+ - LGPL-2.1
+ - LGPL-2.1-only
+ - LGPL-2.1-or-later
+ - LGPL-3.0+
+ - LGPL-3.0
+ - LGPL-3.0-linking-exception
+ - LGPL-3.0-only
+ - LGPL-3.0-or-later
+ - LGPLLR
+ - GPL-1.0+
+ - GPL-1.0
+ - GPL-1.0-only
+ - GPL-1.0-or-later
+ - GPL-2.0+
+ - GPL-2.0
+ - GPL-2.0-only
+ - GPL-2.0-or-later
+ - GPL-2.0-with-autoconf-exception
+ - GPL-2.0-with-bison-exception
+ - GPL-2.0-with-classpath-exception
+ - GPL-2.0-with-font-exception
+ - GPL-2.0-with-GCC-exception
+ - GPL-3.0+
+ - GPL-3.0
+ - GPL-3.0-linking-exception
+ - GPL-3.0-linking-source-exception
+ - GPL-3.0-only
+ - GPL-3.0-or-later
+ - GPL-3.0-with-autoconf-exception
+ - GPL-3.0-with-GCC-exception
+ - GPL-CC-1.0
+ - QPL-1.0
+ - Sleepycat
+ - SSPL-1.0
+ - CPOL-1.02
+ - NPL-1.0
+ - NPL-1.1
diff --git a/commands/deps.go b/commands/deps.go
index cac7d08..0c38b7a 100644
--- a/commands/deps.go
+++ b/commands/deps.go
@@ -29,5 +29,6 @@ var Deps = &cobra.Command{
}
func init() {
- Deps.AddCommand(ResolveCommand)
+ Deps.AddCommand(DepsResolveCommand)
+ Deps.AddCommand(DepsCheckCommand)
}
diff --git a/commands/deps.go b/commands/deps_check.go
similarity index 69%
copy from commands/deps.go
copy to commands/deps_check.go
index cac7d08..1f4fb93 100644
--- a/commands/deps.go
+++ b/commands/deps_check.go
@@ -19,15 +19,15 @@ package commands
import (
"github.com/spf13/cobra"
-)
-var Deps = &cobra.Command{
- Use: "dependency",
- Aliases: []string{"d", "deps", "dep", "dependencies"},
- Short: "Dependencies related commands; e.g. check, etc.",
- Long: "deps command checks all dependencies of a module and their
transitive dependencies.",
-}
+ "github.com/apache/skywalking-eyes/license-eye/pkg/deps"
+)
-func init() {
- Deps.AddCommand(ResolveCommand)
+var DepsCheckCommand = &cobra.Command{
+ Use: "check",
+ Aliases: []string{"c"},
+ Long: "resolves and check license compatibility in all dependencies
of a module and their transitive dependencies",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return deps.Check(Config.Header.License.SpdxID, &Config.Deps)
+ },
}
diff --git a/commands/deps_resolve.go b/commands/deps_resolve.go
index c142d6e..4a03927 100644
--- a/commands/deps_resolve.go
+++ b/commands/deps_resolve.go
@@ -26,7 +26,7 @@ import (
"github.com/apache/skywalking-eyes/license-eye/pkg/deps"
)
-var ResolveCommand = &cobra.Command{
+var DepsResolveCommand = &cobra.Command{
Use: "resolve",
Aliases: []string{"r"},
Long: "resolves all dependencies of a module and their transitive
dependencies",
diff --git a/pkg/deps/check.go b/pkg/deps/check.go
new file mode 100644
index 0000000..a164dcc
--- /dev/null
+++ b/pkg/deps/check.go
@@ -0,0 +1,90 @@
+//
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package deps
+
+import (
+ "fmt"
+ "path/filepath"
+ "strings"
+
+ "gopkg.in/yaml.v3"
+
+ "github.com/apache/skywalking-eyes/license-eye/assets"
+ "github.com/apache/skywalking-eyes/license-eye/internal/logger"
+)
+
+type compatibilityMatrix struct {
+ Compatible []string `yaml:"compatible"`
+ Incompatible []string `yaml:"incompatible"`
+}
+
+var matrices = make(map[string]compatibilityMatrix)
+
+func init() {
+ dir := "compatibility"
+ files, err := assets.AssetDir(dir)
+ if err != nil {
+ logger.Log.Fatalln("Failed to list assets/compatibility
directory:", err)
+ }
+ for _, file := range files {
+ name := file.Name()
+ matrix := compatibilityMatrix{}
+ if bytes, err := assets.Asset(filepath.Join(dir, name)); err !=
nil {
+ logger.Log.Fatalln("Failed to read compatibility
file:", name, err)
+ } else if err := yaml.Unmarshal(bytes, &matrix); err != nil {
+ logger.Log.Fatalln("Failed to unmarshal compatibility
file:", file, err)
+ }
+ matrices[strings.TrimSuffix(name, filepath.Ext(name))] = matrix
+ }
+}
+
+func Check(mainLicenseSpdxID string, config *ConfigDeps) error {
+ report := Report{}
+ if err := Resolve(config, &report); err != nil {
+ return nil
+ }
+
+ matrix := matrices[mainLicenseSpdxID]
+ var incompatibleResults []*Result
+ for _, result := range append(report.Resolved, report.Skipped...) {
+ compare := func(list []string) bool {
+ for _, com := range list {
+ if result.LicenseSpdxID == com {
+ return true
+ }
+ }
+ return false
+ }
+ if compatible := compare(matrix.Compatible); compatible {
+ continue
+ }
+ if incompatible := compare(matrix.Incompatible); incompatible {
+ incompatibleResults = append(incompatibleResults,
result)
+ }
+ }
+
+ if len(incompatibleResults) > 0 {
+ str := ""
+ for _, r := range incompatibleResults {
+ str += fmt.Sprintf("\nLicense: %v Dependency: %v",
r.LicenseSpdxID, r.Dependency)
+ }
+ return fmt.Errorf("the following licenses are incompatible with
the main license: %v %v", mainLicenseSpdxID, str)
+ }
+
+ return nil
+}
diff --git a/pkg/license/identifier_test.go b/pkg/license/identifier_test.go
new file mode 100644
index 0000000..ea7749b
--- /dev/null
+++ b/pkg/license/identifier_test.go
@@ -0,0 +1,70 @@
+//
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package license
+
+import "testing"
+
+func TestIdentify(t *testing.T) {
+ tests := []struct {
+ name string
+ content string
+ want string
+ }{
+ {
+ name: "License per portion",
+ content: `MIT License
+
+Copyright (c) 2017 Blake Gentry
+
+This license applies to the non-Windows portions of this library. The Windows
+portion maintains its own Apache 2.0 license.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+`,
+ want: `MIT`,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := Identify("", tt.content)
+ if err != nil {
+ t.Errorf("Identify() error = %v", err)
+ return
+ }
+ if got != tt.want {
+ t.Errorf("Identify() got = %v, want %v", got,
tt.want)
+ }
+ })
+ }
+}
diff --git a/pkg/license/norm.go b/pkg/license/norm.go
index 3687290..46ef393 100644
--- a/pkg/license/norm.go
+++ b/pkg/license/norm.go
@@ -178,6 +178,11 @@ var (
},
{
+ regexp.MustCompile(`(?im)This license applies to .+?
portions of this .+?\. The .+? maintains its own .+? license\.`),
+ "",
+ },
+
+ {
regexp.MustCompile(`(?im)\(including the next
paragraph\)`),
"",
},
@@ -224,6 +229,11 @@ var (
regexp.MustCompile(`(?m)^\s*Copyright (\([cC©]\))?.+$`),
"",
},
+ // All rights reserved
+ {
+ regexp.MustCompile(`(?m)^\s*All rights reserved\.?$`),
+ "",
+ },
// This should be the last one processor
{