You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by ke...@apache.org on 2020/12/23 15:47:04 UTC

[skywalking-eyes] branch feature/spdx created (now 9679831)

This is an automated email from the ASF dual-hosted git repository.

kezhenxu94 pushed a change to branch feature/spdx
in repository https://gitbox.apache.org/repos/asf/skywalking-eyes.git.


      at 9679831  Add feature to support spdx-id to ease the configurations

This branch includes the following new commits:

     new 9679831  Add feature to support spdx-id to ease the configurations

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[skywalking-eyes] 01/01: Add feature to support spdx-id to ease the configurations

Posted by ke...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kezhenxu94 pushed a commit to branch feature/spdx
in repository https://gitbox.apache.org/repos/asf/skywalking-eyes.git

commit 96798318e4dd3bcb6f90eb7e02bccc4d6cd627c7
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Wed Dec 23 23:44:26 2020 +0800

    Add feature to support spdx-id to ease the configurations
---
 .licenserc.yaml                                    |  67 +++++-----
 license-eye/Makefile                               |   2 +-
 license-eye/README.adoc                            | 136 ++++++++++++++++++---
 .../assets/lcs-templates/Apache-2.0-ASF.txt        |  16 +++
 license-eye/assets/lcs-templates/Apache-2.0.txt    |  13 ++
 license-eye/pkg/header/check.go                    |   2 +-
 license-eye/pkg/header/check_test.go               |   4 +-
 license-eye/pkg/header/config.go                   |  50 +++++++-
 license-eye/pkg/header/fix.go                      |   2 +-
 license-eye/pkg/header/fix_test.go                 |   4 +-
 license-eye/pkg/review/header.go                   |   2 +-
 license-eye/test/config_test.go                    |  79 ++++++++++++
 .../test/testdata/.licenserc_for_test_check.yaml   |  31 ++---
 .../test/testdata/.licenserc_for_test_fix.yaml     |  31 ++---
 license-eye/test/testdata/test-spdx-asf.yaml       |   4 +
 license-eye/test/testdata/test-spdx.yaml           |   4 +
 16 files changed, 357 insertions(+), 90 deletions(-)

diff --git a/.licenserc.yaml b/.licenserc.yaml
index d77578b..5b6a539 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -17,43 +17,45 @@
 # under the License.
 #
 header: # `header` section is configurations for source codes license header.
-  license: | # `license` will be used as the content when `fix` command needs to insert a license header.
-    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
+  license:
+    spdx-id: Apache-2.0 # the spdx id of the license, it's convenient when your license is standard SPDX license.
+    copyright-owner: Apache Software Foundation # the copyright owner to replace the [owner] in the `spdx-id` template.
+    content: | # `license` will be used as the content when `fix` command needs to insert a license header.
+      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
+          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.
+      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.
 
-  # `pattern` is optional regexp if all the file headers are the same as `license` (linebreaks doesn't matter);
-  # In the `pattern`, all punctuations should be removed unless they are part of the regex;
-  pattern: |
-    Licensed to the Apache Software Foundation under one or more contributor
-    license agreements. See the NOTICE file distributed with
-    this work for additional information regarding copyright
-    ownership. The Apache Software Foundation 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
+    # `pattern` is optional regexp if all the file headers are the same as `license` or the license of `spdx-id` and `copyright-owner`.
+    pattern: |
+      Licensed to the Apache Software Foundation under one or more contributor
+      license agreements. See the NOTICE file distributed with
+      this work for additional information regarding copyright
+      ownership. The Apache Software Foundation 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
+          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.
+      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.
 
   paths: # `paths` are the path list that will be checked (and fixed) by license-eye, default is ['**'].
     - '**'
@@ -67,6 +69,7 @@ header: # `header` section is configurations for source codes license header.
     - '**/go.sum'
     - 'LICENSE'
     - 'NOTICE'
+    - '**/assets/lcs-templates/**'
     - '**/assets/languages.yaml'
     - '**/assets/assets.gen.go'
 
diff --git a/license-eye/Makefile b/license-eye/Makefile
index 09f9fca..96d060f 100644
--- a/license-eye/Makefile
+++ b/license-eye/Makefile
@@ -57,7 +57,7 @@ license: clean codegen
 .PHONY: codegen
 codegen: clean
 	$(GO_BINDATA) -v || curl -Lo $(GO_BINDATA) https://github.com/kevinburke/go-bindata/releases/download/v3.11.0/go-bindata-$(OSNAME)-amd64 && chmod +x $(GO_BINDATA)
-	$(GO_BINDATA) --nocompress --nometadata --pkg assets --ignore '.*\.go' -o "assets/assets.gen.go" assets/
+	$(GO_BINDATA) --nocompress --nometadata --pkg assets --ignore '.*\.go' -o "assets/assets.gen.go" assets/...
 
 .PHONY: test
 test: clean codegen
diff --git a/license-eye/README.adoc b/license-eye/README.adoc
index 3dd5c0b..1a664de 100644
--- a/license-eye/README.adoc
+++ b/license-eye/README.adoc
@@ -18,41 +18,66 @@
 // 
 = License-Eye
 :repo: https://github.com/apache/skywalking-eyes
+:revision: main
+:name: License-Eye
 
 A full-featured license guard to check and fix license headers and dependencies' licenses.
 
-== Install
+== Usage
 
-[subs="attributes",source,bash]
+You can use {name} in GitHub Actions or in your local machine.
+
+=== GitHub Actions
+
+To use License-Eye in GitHub Actions, add a step in your GitHub workflow.
+
+[subs="attributes",source,yaml]
 ----
-git clone {repo}
-cd skywalking-eyes/license-eye
-make
+- name: Check License Header
+  uses: apache/skywalking-eyes@{revision}      # always prefer to use a revision instead of `main`.
+  env:
+    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # needed only when you want License-Eye to comment on the pull request.
 ----
 
-== Usage
+Add a `.licenserc.yaml` in the root of your project, for Apache Software Foundation projects, the following configuration should be enough.
 
-[source,bash]
+[source,yaml]
 ----
-$ license-eye -c ./licenserc.yaml header check
-$ license-eye -c ./licenserc.yaml header fix
+header:
+  license:
+    spdx-id: Apache-2.0
+    copyright-owner: Apache Software Foundation
+
+  paths-ignore:
+    - 'dist'
+    - 'licenses'
+    - '**/*.md'
+    - 'LICENSE'
+    - 'NOTICE'
+
+  comment: on-failure
 ----
 
-== Configuration
+NOTE: The full configurations can be found in <<Configurations,the configuration section>>.
 
-[source,yaml]
-.link:../.licenserc.yaml[.licenserc.yaml]
+=== Use as a Binary
+
+==== Install
+
+[subs="attributes",source,bash]
 ----
-include::../.licenserc.yaml[]
+$ git clone {repo}
+$ cd skywalking-eyes/license-eye
+$ make build
 ----
 
-== Check License Header
+===== Check License Header
 
 [source,bash]
 ----
-$ bin/license-eye -c test/testdata/.licenserc_for_test_fix.yaml header check
+$ bin/darwin/license-eye -c test/testdata/.licenserc_for_test_fix.yaml header check
 
-INFO Loading configuration from file: test/testdata/.licenserc_for_test.yaml serc_for_test.yaml
+INFO Loading configuration from file: test/testdata/.licenserc_for_test.yaml
 INFO Totally checked 23 files, valid: 8, invalid: 8, ignored: 7, fixed: 0
 ERROR The following files don't have a valid license header:
 test/testdata/include_test/without_license/testcase.go
@@ -66,16 +91,88 @@ test/testdata/include_test/without_license/testcase.yml
 exit status 1
 ----
 
-== Fix License Header
+==== Fix License Header
 
 [source,bash]
 ----
-$ bin/license-eye -c test/testdata/.licenserc_for_test_fix.yaml header fix
+$ bin/darwin/license-eye -c test/testdata/.licenserc_for_test_fix.yaml header fix
 
 INFO Loading configuration from file: test/testdata/.licenserc_for_test_fix.yaml
 INFO Totally checked 16 files, valid: 7, invalid: 8, ignored: 1, fixed: 8
 ----
 
+== Configurations
+
+[source,yaml]
+----
+header: # <1>
+  license:
+    spdx-id: Apache-2.0 # <2>
+    copyright-owner: Apache Software Foundation # <3>
+    content: | # <4>
+      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.
+
+    pattern: | # <5>
+      Licensed to the Apache Software Foundation under one or more contributor
+      license agreements. See the NOTICE file distributed with
+      this work for additional information regarding copyright
+      ownership. The Apache Software Foundation 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.
+
+  paths: # <6>
+    - '**'
+
+  paths-ignore: # <7>
+    - 'dist'
+    - 'licenses'
+    - '**/*.md'
+    - '**/testdata/**'
+    - '**/go.mod'
+    - '**/go.sum'
+    - 'LICENSE'
+    - 'NOTICE'
+    - '**/assets/languages.yaml'
+    - '**/assets/assets.gen.go'
+
+  comment: on-failure # <8>
+----
+<1> `header` section is configurations for source codes license header.
+<2> The link:https://spdx.org/licenses/[SPDX ID] of the license, it's convenient when your license is standard SPDX license, so that you can simply specify this identifier without copying the whole license `content` or `pattern`. This will be used as the content when `fix` command needs to insert a license header.
+<3> The copyright owner to replace the `[owner]` in the `SPDX-ID` license template.
+<4> If you are not using the standard license txt, you can paste your license text here, this will be used as the content when `fix` command needs to insert a license header, if both `license` and `SPDX-ID` are specified, `license` wins.
+<5> `pattern` is an optional regexp. You don't need this if all the file headers are the same as `license` or the license of `SPDX-ID`, otherwise you need to compose a pattern that matches your license texts.
+<6> `paths` are the path list that will be checked (and fixed) by license-eye, default is ['**']. Formats like `**/*.md` and `**/bin/**` are supported.
+<7> `paths-ignore` are the path list that will be ignored by license-eye. By default, `.git` and the content in `.gitignore` will be inflated into the `paths-ignore` list.
+<8> On what condition license-eye will comment the check results on the pull request, `on-failure`, `always`, `never`. Options other than `never` requre the environment variable `GITHUB_TOKEN` to be set.
+
+NOTE: When the `SPDX-ID` is Apache-2.0 and the owner is Apache Software foundation, the content would be link:https://www.apache.org/legal/src-headers.html#headers[a dedicated license] link:https://www.apache.org/foundation/license-faq.html#Apply-My-Software[specified by the ASF], otherwise, the license would be link:https://www.apache.org/foundation/license-faq.html#Apply-My-Software[the standard one].
+
 == Supported File Types
 
 The `check` command theoretically supports all kinds of file types, while the supported file types of `fix` command can be found link:assets/languages.yaml[in this YAML file].
@@ -98,7 +195,8 @@ include::assets/styles.yaml[tags=SlashAsterisk]
 
 == Contribution
 
-If you found any file type is not supported by the aforementioned configurations, feel free to link:https://github.com/apache/skywalking-eyes/pulls[open a pull request] to add the configuration into the 2 files.
+- If you find any file type should be supported by the aforementioned configurations but is not listed there, feel free to link:https://github.com/apache/skywalking-eyes/pulls[open a pull request] to add the configuration into the 2 files.
+- If you find the license template of an SPDX ID is not supported, feel free to link:https://github.com/apache/skywalking-eyes/pulls[open a pull request] to add it into link:assets/lcs-templates[the template folder].
 
 == License
 
diff --git a/license-eye/assets/lcs-templates/Apache-2.0-ASF.txt b/license-eye/assets/lcs-templates/Apache-2.0-ASF.txt
new file mode 100644
index 0000000..60b675e
--- /dev/null
+++ b/license-eye/assets/lcs-templates/Apache-2.0-ASF.txt
@@ -0,0 +1,16 @@
+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.
diff --git a/license-eye/assets/lcs-templates/Apache-2.0.txt b/license-eye/assets/lcs-templates/Apache-2.0.txt
new file mode 100644
index 0000000..83cfa23
--- /dev/null
+++ b/license-eye/assets/lcs-templates/Apache-2.0.txt
@@ -0,0 +1,13 @@
+Copyright [year] [owner]
+
+Licensed 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.
diff --git a/license-eye/pkg/header/check.go b/license-eye/pkg/header/check.go
index c32279b..ff59b34 100644
--- a/license-eye/pkg/header/check.go
+++ b/license-eye/pkg/header/check.go
@@ -139,7 +139,7 @@ func CheckFile(file string, config *ConfigHeader, result *pkg.Result) error {
 }
 
 func satisfy(content, license string, pattern *regexp.Regexp) bool {
-	if index := strings.Index(content, license); license != "" && index >= 0 {
+	if index := strings.Index(content, license); strings.TrimSpace(license) != "" && index >= 0 {
 		return index < LicenseLocationThreshold
 	}
 
diff --git a/license-eye/pkg/header/check_test.go b/license-eye/pkg/header/check_test.go
index ca8e1bb..cbd898b 100644
--- a/license-eye/pkg/header/check_test.go
+++ b/license-eye/pkg/header/check_test.go
@@ -80,7 +80,7 @@ func TestCheckFile(t *testing.T) {
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if strings.TrimSpace(c.Header.License) == "" {
+			if strings.TrimSpace(c.Header.GetLicenseContent()) == "" {
 				t.Errorf("License should not be empty")
 			}
 			if err := CheckFile(tt.file, &c.Header, tt.result); (err != nil) != tt.wantErr {
@@ -127,7 +127,7 @@ func TestCheckFileFailure(t *testing.T) {
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if strings.TrimSpace(c.Header.License) == "" {
+			if strings.TrimSpace(c.Header.GetLicenseContent()) == "" {
 				t.Errorf("License should not be empty")
 			}
 			if err := CheckFile(tt.file, &c.Header, tt.result); (err != nil) != tt.wantErr {
diff --git a/license-eye/pkg/header/config.go b/license-eye/pkg/header/config.go
index 5d4595b..5549a24 100644
--- a/license-eye/pkg/header/config.go
+++ b/license-eye/pkg/header/config.go
@@ -19,10 +19,14 @@ package header
 
 import (
 	"bufio"
+	"fmt"
 	"os"
 	"regexp"
+	"strconv"
 	"strings"
+	"time"
 
+	"github.com/apache/skywalking-eyes/license-eye/assets"
 	"github.com/apache/skywalking-eyes/license-eye/internal/logger"
 	"github.com/apache/skywalking-eyes/license-eye/pkg/license"
 
@@ -35,10 +39,19 @@ var (
 	Always    CommentOption = "always"
 	Never     CommentOption = "never"
 	OnFailure CommentOption = "on-failure"
+
+	ASFNames = regexp.MustCompile("(?i)(the )?(Apache Software Foundation|ASF)")
 )
 
+type LicenseConfig struct {
+	SpdxID         string `yaml:"spdx-id"`
+	CopyrightOwner string `yaml:"copyright-owner"`
+	Content        string `yaml:"content"`
+	Pattern        string `yaml:"pattern"`
+}
+
 type ConfigHeader struct {
-	License     string        `yaml:"license"`
+	License     LicenseConfig `yaml:"license"`
 	Pattern     string        `yaml:"pattern"`
 	Paths       []string      `yaml:"paths"`
 	PathsIgnore []string      `yaml:"paths-ignore"`
@@ -48,7 +61,7 @@ type ConfigHeader struct {
 // NormalizedLicense returns the normalized string of the license content,
 // "normalized" means the linebreaks and Punctuations are all trimmed.
 func (config *ConfigHeader) NormalizedLicense() string {
-	return license.Normalize(config.License)
+	return license.Normalize(config.GetLicenseContent())
 }
 
 func (config *ConfigHeader) NormalizedPattern() *regexp.Regexp {
@@ -109,3 +122,36 @@ func (config *ConfigHeader) Finalize() error {
 
 	return nil
 }
+
+func (config *ConfigHeader) GetLicenseContent() string {
+	if c := strings.TrimSpace(config.License.Content); c != "" {
+		return c
+	}
+	c, err := readLicenseFromSpdx(config)
+	if err != nil {
+		logger.Log.Warnln(err)
+		return ""
+	}
+	return c
+}
+
+func readLicenseFromSpdx(config *ConfigHeader) (string, error) {
+	spdxID, owner := config.License.SpdxID, config.License.CopyrightOwner
+	filename := fmt.Sprintf("assets/lcs-templates/%v.txt", spdxID)
+
+	if spdxID == "Apache-2.0" && ASFNames.MatchString(owner) {
+		// Note that the Apache Software Foundation uses a different source header that is related to our use of a CLA.
+		// Our instructions for our project's source headers are here (https://www.apache.org/legal/src-headers.html#headers).
+		filename = "assets/lcs-templates/Apache-2.0-ASF.txt"
+	}
+
+	content, err := assets.Asset(filename)
+	if err != nil {
+		return "", fmt.Errorf("failed to find a license template for spdx id %v, %w", spdxID, err)
+	}
+	template := string(content)
+	template = strings.Replace(template, "[year]", strconv.Itoa(time.Now().Year()), 1)
+	template = strings.Replace(template, "[owner]", owner, 1)
+
+	return template, nil
+}
diff --git a/license-eye/pkg/header/fix.go b/license-eye/pkg/header/fix.go
index f5e061d..fb8413c 100644
--- a/license-eye/pkg/header/fix.go
+++ b/license-eye/pkg/header/fix.go
@@ -99,7 +99,7 @@ func GenerateLicenseHeader(style *comments.CommentStyle, config *ConfigHeader) (
 		return "", err
 	}
 
-	middleLines := strings.Split(config.License, "\n")
+	middleLines := strings.Split(config.GetLicenseContent(), "\n")
 	for i, line := range middleLines {
 		middleLines[i] = strings.TrimRight(fmt.Sprintf("%v %v", style.Middle, line), " ")
 	}
diff --git a/license-eye/pkg/header/fix_test.go b/license-eye/pkg/header/fix_test.go
index 57da4c4..dc6bfe0 100644
--- a/license-eye/pkg/header/fix_test.go
+++ b/license-eye/pkg/header/fix_test.go
@@ -26,9 +26,11 @@ import (
 )
 
 var config = &ConfigHeader{
-	License: `Apache License 2.0
+	License: LicenseConfig{
+		Content: `Apache License 2.0
   http://www.apache.org/licenses/LICENSE-2.0
 Apache License 2.0`,
+	},
 }
 
 func TestFix(t *testing.T) {
diff --git a/license-eye/pkg/review/header.go b/license-eye/pkg/review/header.go
index 7ec342f..4ad84e7 100644
--- a/license-eye/pkg/review/header.go
+++ b/license-eye/pkg/review/header.go
@@ -111,7 +111,7 @@ func init() {
 
 // Header reviews the license header, including suggestions on the pull request and an overview of the checks.
 func Header(result *pkg.Result, config *config2.Config) error {
-	if !result.HasFailure() || !IsPR() || gh == nil {
+	if !result.HasFailure() || !IsPR() || gh == nil || config.Header.Comment == header2.Never {
 		return nil
 	}
 
diff --git a/license-eye/test/config_test.go b/license-eye/test/config_test.go
new file mode 100644
index 0000000..82c64fb
--- /dev/null
+++ b/license-eye/test/config_test.go
@@ -0,0 +1,79 @@
+//
+// 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 test
+
+import (
+	"strconv"
+	"testing"
+	"time"
+
+	config2 "github.com/apache/skywalking-eyes/license-eye/pkg/config"
+)
+
+func TestConfigHeaderSpdxASF(t *testing.T) {
+	c := config2.Config{}
+	if err := c.Parse("./testdata/test-spdx-asf.yaml"); err != nil {
+		t.Error("unexpected error", err)
+	}
+
+	expected := `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.
+`
+	if actual := c.Header.GetLicenseContent(); actual != expected {
+		t.Errorf("Actual: \n%v\nExpected: \n%v", actual, expected)
+	}
+}
+
+func TestConfigHeaderSpdxPlain(t *testing.T) {
+	c := config2.Config{}
+	if err := c.Parse("./testdata/test-spdx.yaml"); err != nil {
+		t.Error("unexpected error", err)
+	}
+
+	expected := `Copyright ` + strconv.Itoa(time.Now().Year()) + ` kezhenxu94
+
+Licensed 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.
+`
+	if actual := c.Header.GetLicenseContent(); actual != expected {
+		t.Errorf("Actual: \n%v\nExpected: \n%v", actual, expected)
+	}
+}
diff --git a/license-eye/test/testdata/.licenserc_for_test_check.yaml b/license-eye/test/testdata/.licenserc_for_test_check.yaml
index eee7d39..d5cdec0 100644
--- a/license-eye/test/testdata/.licenserc_for_test_check.yaml
+++ b/license-eye/test/testdata/.licenserc_for_test_check.yaml
@@ -1,21 +1,22 @@
 header:
-  license: |
-    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
+  license:
+    content: |
+      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
+          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.
+      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.
 
   paths:
     - 'test/testdata/**'
diff --git a/license-eye/test/testdata/.licenserc_for_test_fix.yaml b/license-eye/test/testdata/.licenserc_for_test_fix.yaml
index facb12f..4663f0b 100644
--- a/license-eye/test/testdata/.licenserc_for_test_fix.yaml
+++ b/license-eye/test/testdata/.licenserc_for_test_fix.yaml
@@ -1,21 +1,22 @@
 header:
-  license: |
-    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
+  license:
+    content: |
+      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
+          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.
+      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.
 
   paths:
     - 'test/testdata/include_test/**'
diff --git a/license-eye/test/testdata/test-spdx-asf.yaml b/license-eye/test/testdata/test-spdx-asf.yaml
new file mode 100644
index 0000000..98b80d5
--- /dev/null
+++ b/license-eye/test/testdata/test-spdx-asf.yaml
@@ -0,0 +1,4 @@
+header:
+  license:
+    spdx-id: Apache-2.0
+    copyright-owner: Apache Software Foundation
diff --git a/license-eye/test/testdata/test-spdx.yaml b/license-eye/test/testdata/test-spdx.yaml
new file mode 100644
index 0000000..4391ce2
--- /dev/null
+++ b/license-eye/test/testdata/test-spdx.yaml
@@ -0,0 +1,4 @@
+header:
+  license:
+    spdx-id: Apache-2.0
+    copyright-owner: kezhenxu94