licensing: Add presubmit check for license errors

If an ebuild is modified, check if the LICENSE field in the ebuild is
whitespace delimited, and whether the the license(s) stated in the
ebuild exsits in the stock or custom directories. Note that some
packages have copyright file in their source, this presubmission check
does not check the source and may display an error in this case.

BUG=chromium:318364
CQ-DEPEND=CL:177398
CQ-DEPEND=CL:177693
TEST=repo upload with incorrect licenses

Change-Id: Ie96bc62f2c7c710d61659403c91153287b4291a8
Reviewed-on: https://chromium-review.googlesource.com/178875
Reviewed-by: Yu-Ju Hong <yjhong@chromium.org>
Commit-Queue: Yu-Ju Hong <yjhong@chromium.org>
Tested-by: Yu-Ju Hong <yjhong@chromium.org>
diff --git a/pre-upload.py b/pre-upload.py
index 07ca533..5320577 100755
--- a/pre-upload.py
+++ b/pre-upload.py
@@ -25,6 +25,7 @@
   sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), '..', '..'))
 
 from chromite.lib import patch
+from chromite.licensing import licenses
 
 
 COMMON_INCLUDED_PATHS = [
@@ -448,6 +449,33 @@
   return None
 
 
+def _check_ebuild_licenses(_project, commit):
+  """Check if the LICENSE field in the ebuild is correct."""
+  affected_paths = _get_affected_files(commit)
+  touched_ebuilds = [x for x in affected_paths if x.endswith('.ebuild')]
+
+  # A list of licenses to ignore for now.
+  LICENSES_IGNORE = ['||', '(', ')', 'Proprietary', 'as-is']
+
+  for ebuild in touched_ebuilds:
+    # Skip virutal packages.
+    if ebuild.split('/')[-3] == 'virtual':
+      continue
+
+    try:
+      license_types = licenses.GetLicenseTypesFromEbuild(ebuild)
+    except ValueError as e:
+      return HookFailure(e.message, [ebuild])
+
+    # Also ignore licenses ending with '?'
+    for license_type in [x for x in license_types
+                         if x not in LICENSES_IGNORE and not x.endswith('?')]:
+      try:
+        licenses.Licensing.FindLicenseType(license_type)
+      except AssertionError as e:
+        return HookFailure(e.message, [ebuild])
+
+
 def _check_change_has_proper_changeid(project, commit):
   """Verify that Change-ID is present in last paragraph of commit message."""
   desc = _get_commit_desc(commit)
@@ -595,6 +623,7 @@
     _check_change_has_valid_cq_depend,
     _check_change_has_test_field,
     _check_change_has_proper_changeid,
+    _check_ebuild_licenses,
     _check_no_stray_whitespace,
     _check_no_long_lines,
     _check_license,