Skip to content

Commit be88844

Browse files
committed
Move Bazel code to its own file #1678
Signed-off-by: Jono Yang <[email protected]>
1 parent b1819fe commit be88844

File tree

3 files changed

+124
-7
lines changed

3 files changed

+124
-7
lines changed

src/packagedcode/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from packagedcode import pypi
4242
from packagedcode import rpm
4343
from packagedcode import rubygems
44+
from packagedcode import bazel
4445
from packagedcode import buck
4546

4647

@@ -84,7 +85,7 @@
8485
models.IsoImagePackage,
8586
models.SquashfsPackage,
8687
chef.ChefPackage,
87-
build.BazelPackage,
88+
bazel.BazelPackage,
8889
buck.BuckPackage,
8990
build.AutotoolsPackage,
9091
conda.CondaPackage,

src/packagedcode/bazel.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Copyright (c) 2019 nexB Inc. and others. All rights reserved.
2+
# http://nexb.com and https://github.com/nexB/scancode-toolkit/
3+
# The ScanCode software is licensed under the Apache License version 2.0.
4+
# Data generated with ScanCode require an acknowledgment.
5+
# ScanCode is a trademark of nexB Inc.
6+
#
7+
# You may not use this software except in compliance with the License.
8+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
9+
# Unless required by applicable law or agreed to in writing, software distributed
10+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
# specific language governing permissions and limitations under the License.
13+
#
14+
# When you publish or redistribute any data created with ScanCode or any ScanCode
15+
# derivative work, you must accompany this data with the following acknowledgment:
16+
#
17+
# Generated with ScanCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
18+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
19+
# ScanCode should be considered or used as legal advice. Consult an Attorney
20+
# for any legal advice.
21+
# ScanCode is a free software code scanning tool from nexB Inc. and others.
22+
# Visit https://github.com/nexB/scancode-toolkit/ for support and download.
23+
24+
from __future__ import absolute_import
25+
from __future__ import print_function
26+
from __future__ import unicode_literals
27+
28+
from collections import defaultdict
29+
from collections import OrderedDict
30+
import ast
31+
import os
32+
33+
import attr
34+
35+
from commoncode import fileutils
36+
from packagedcode.build import BaseBuildManifestPackage
37+
from packagedcode.utils import combine_expressions
38+
from scancode.api import get_licenses
39+
40+
41+
@attr.s()
42+
class BazelPackage(BaseBuildManifestPackage):
43+
metafiles = ('BUILD',)
44+
default_type = 'bazel'
45+
46+
@classmethod
47+
def recognize(cls, location):
48+
if not cls._is_build_manifest(location):
49+
return
50+
for package in bazel_parse(location):
51+
yield package
52+
53+
def compute_normalized_license(self):
54+
return compute_normalized_license(
55+
self.declared_license,
56+
manifest_parent_path=self.root_path
57+
)
58+
59+
60+
def bazel_parse(location):
61+
build_rules = defaultdict(list)
62+
# Thanks to the Skylark language being a Python DSL, we can use the `ast`
63+
# library to parse Bazel BUILD files
64+
with open(location, 'rb') as f:
65+
tree = ast.parse(f.read())
66+
for statement in tree.body:
67+
if (isinstance(statement, ast.Expr)
68+
or isinstance(statement, ast.Call)
69+
or isinstance(statement, ast.Assign)
70+
and isinstance(statement.value, ast.Call)
71+
and isinstance(statement.value.func, ast.Name)):
72+
rule_name = statement.value.func.id
73+
# Process the rule arguments
74+
args = OrderedDict()
75+
for kw in statement.value.keywords:
76+
arg_name = kw.arg
77+
if isinstance(kw.value, ast.Str):
78+
args[arg_name] = kw.value.s
79+
if isinstance(kw.value, ast.List):
80+
# We collect the elements of a list if the element is not a function call
81+
args[arg_name] = [elt.s for elt in kw.value.elts if not isinstance(elt, ast.Call)]
82+
if args:
83+
build_rules[rule_name].append(args)
84+
85+
if build_rules:
86+
for rule_name, rule_instances_args in build_rules.items():
87+
for args in rule_instances_args:
88+
name = args.get('name')
89+
if not name:
90+
continue
91+
license_files = args.get('licenses')
92+
yield BazelPackage(
93+
name=name,
94+
declared_license=license_files,
95+
root_path=fileutils.parent_directory(location)
96+
)
97+
else:
98+
# If we don't find anything in the BUCK file, we yield a Package with
99+
# the parent directory as the name, like the default implementation of
100+
# `recognize()` for `BaseBuildManifestPackage`
101+
yield BazelPackage(
102+
# we use the parent directory as a name
103+
name=fileutils.file_name(fileutils.parent_directory(location))
104+
)
105+
106+
107+
def compute_normalized_license(declared_license, manifest_parent_path):
108+
"""
109+
Return a normalized license expression string detected from a list of
110+
declared license items.
111+
"""
112+
if not declared_license or not manifest_parent_path:
113+
return
114+
115+
license_expressions = []
116+
for license_file in declared_license:
117+
license_file_path = os.path.join(manifest_parent_path, license_file)
118+
if os.path.exists(license_file_path) and os.path.isfile(license_file_path):
119+
licenses = get_licenses(license_file_path)
120+
license_expressions.extend(licenses.get('license_expressions', []))
121+
122+
return combine_expressions(license_expressions)

src/packagedcode/build.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,3 @@ def _is_build_manifest(cls, location):
8989
class AutotoolsPackage(BaseBuildManifestPackage):
9090
metafiles = ('configure', 'configure.ac',)
9191
default_type = 'autotools'
92-
93-
94-
@attr.s()
95-
class BazelPackage(BaseBuildManifestPackage):
96-
metafiles = ('BUILD',)
97-
default_type = 'bazel'

0 commit comments

Comments
 (0)