]> git.proxmox.com Git - mirror_edk2.git/commitdiff
.pytool/Plugin: Add a plugin LicenseCheck
authorShenglei Zhang <shenglei.zhang@intel.com>
Fri, 10 Jul 2020 07:37:59 +0000 (15:37 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 31 Jul 2020 02:49:51 +0000 (02:49 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2691
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2833
Add a plugin to check license conflict for new added
files in a patch. It will report out errors when meeting
files which are not contributed under BSD-2-Clause-Patent.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
.pytool/Plugin/LicenseCheck/LicenseCheck.py [new file with mode: 0644]
.pytool/Plugin/LicenseCheck/LicenseCheck_plug_in.yaml [new file with mode: 0644]
.pytool/Plugin/LicenseCheck/Readme.md [new file with mode: 0644]

diff --git a/.pytool/Plugin/LicenseCheck/LicenseCheck.py b/.pytool/Plugin/LicenseCheck/LicenseCheck.py
new file mode 100644 (file)
index 0000000..5733f7b
--- /dev/null
@@ -0,0 +1,115 @@
+# @file LicenseCheck.py\r
+#\r
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+\r
+import os\r
+import logging\r
+import re\r
+from io import StringIO\r
+from typing import List, Tuple\r
+from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin\r
+from edk2toolext.environment.var_dict import VarDict\r
+from edk2toollib.utility_functions import RunCmd\r
+\r
+\r
+class LicenseCheck(ICiBuildPlugin):\r
+\r
+    """\r
+    A CiBuildPlugin to check the license for new added files.\r
+\r
+    Configuration options:\r
+    "LicenseCheck": {\r
+        "IgnoreFiles": []\r
+    },\r
+    """\r
+\r
+    license_format_preflix = 'SPDX-License-Identifier'\r
+\r
+    bsd2_patent = 'BSD-2-Clause-Patent'\r
+\r
+    Readdedfileformat = re.compile(r'\+\+\+ b\/(.*)')\r
+\r
+    file_extension_list = [".c", ".h", ".inf", ".dsc", ".dec", ".py", ".bat", ".sh", ".uni", ".yaml",\r
+                           ".fdf", ".inc", "yml", ".asm", ".asm16", ".asl", ".vfr", ".s", ".S", ".aslc",\r
+                           ".nasm", ".nasmb", ".idf", ".Vfr", ".H"]\r
+\r
+    def GetTestName(self, packagename: str, environment: VarDict) -> tuple:\r
+        """ Provide the testcase name and classname for use in reporting\r
+            testclassname: a descriptive string for the testcase can include whitespace\r
+            classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>\r
+\r
+            Args:\r
+              packagename: string containing name of package to build\r
+              environment: The VarDict for the test to run in\r
+            Returns:\r
+                a tuple containing the testcase name and the classname\r
+                (testcasename, classname)\r
+        """\r
+        return ("Check for license for " + packagename, packagename + ".LicenseCheck")\r
+\r
+    ##\r
+    # External function of plugin.  This function is used to perform the task of the ci_build_plugin Plugin\r
+    #\r
+    #   - package is the edk2 path to package.  This means workspace/packagepath relative.\r
+    #   - edk2path object configured with workspace and packages path\r
+    #   - PkgConfig Object (dict) for the pkg\r
+    #   - EnvConfig Object\r
+    #   - Plugin Manager Instance\r
+    #   - Plugin Helper Obj Instance\r
+    #   - Junit Logger\r
+    #   - output_stream the StringIO output stream from this plugin via logging\r
+    def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):\r
+        return_buffer = StringIO()\r
+        params = "diff --unified=0 origin/master HEAD"\r
+        RunCmd("git", params, outstream=return_buffer)\r
+        p = return_buffer.getvalue().strip()\r
+        patch = p.split("\n")\r
+        return_buffer.close()\r
+\r
+        ignore_files = []\r
+        if "IgnoreFiles" in pkgconfig:\r
+            ignore_files = pkgconfig["IgnoreFiles"]\r
+\r
+        self.ok = True\r
+        self.startcheck = False\r
+        self.license = True\r
+        self.all_file_pass = True\r
+        count = len(patch)\r
+        line_index = 0\r
+        for line in patch:\r
+            if line.startswith('--- /dev/null'):\r
+                nextline = patch[line_index + 1]\r
+                added_file = self.Readdedfileformat.search(nextline).group(1)\r
+                added_file_extension = os.path.splitext(added_file)[1]\r
+                if added_file_extension in self.file_extension_list and packagename in added_file:\r
+                    if (self.IsIgnoreFile(added_file, ignore_files)):\r
+                        line_index = line_index + 1\r
+                        continue\r
+                    self.startcheck = True\r
+                    self.license = False\r
+            if self.startcheck and self.license_format_preflix in line:\r
+                if self.bsd2_patent in line:\r
+                    self.license = True\r
+            if line_index + 1 == count or patch[line_index + 1].startswith('diff --') and self.startcheck:\r
+                if not self.license:\r
+                    self.all_file_pass = False\r
+                    error_message = "Invalid license in: " + added_file + " Hint: Only BSD-2-Clause-Patent is accepted."\r
+                    logging.error(error_message)\r
+                self.startcheck = False\r
+                self.license = True\r
+            line_index = line_index + 1\r
+\r
+        if self.all_file_pass:\r
+            tc.SetSuccess()\r
+            return 0\r
+        else:\r
+            tc.SetFailed("License Check {0} Failed. ".format(packagename), "LICENSE_CHECK_FAILED")\r
+            return 1\r
+\r
+    def IsIgnoreFile(self, file: str, ignore_files: List[str]) -> bool:\r
+        for f in ignore_files:\r
+            if f in file:\r
+                return True\r
+        return False\r
diff --git a/.pytool/Plugin/LicenseCheck/LicenseCheck_plug_in.yaml b/.pytool/Plugin/LicenseCheck/LicenseCheck_plug_in.yaml
new file mode 100644 (file)
index 0000000..2fdb0aa
--- /dev/null
@@ -0,0 +1,11 @@
+## @file\r
+# CiBuildPlugin used to check license issues for new added files\r
+#\r
+# Copyright (c) 2020, Intel Corporation. All rights reserved.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+{\r
+  "scope": "cibuild",\r
+  "name": "License Check Test",\r
+  "module": "LicenseCheck"\r
+}\r
diff --git a/.pytool/Plugin/LicenseCheck/Readme.md b/.pytool/Plugin/LicenseCheck/Readme.md
new file mode 100644 (file)
index 0000000..b0e1bbe
--- /dev/null
@@ -0,0 +1,17 @@
+# License Check Plugin\r
+\r
+This CiBuildPlugin scans all new added files in a package to make sure code\r
+is contributed under BSD-2-Clause-Patent.\r
+\r
+## Configuration\r
+\r
+The plugin can be configured to ignore certain files.\r
+\r
+``` yaml\r
+"LicenseCheck": {\r
+    "IgnoreFiles": []\r
+}\r
+```\r
+### IgnoreFiles\r
+\r
+OPTIONAL List of file to ignore.\r