Skip to content

Commit a8acee2

Browse files
chinyeunglipombredanne
authored andcommitted
Scan for bitbake as packages #1243
Signed-off-by: Chin Yeung Li <[email protected]> Signed-off-by: Philippe Ombredanne <[email protected]>
1 parent e4abe78 commit a8acee2

File tree

11 files changed

+483
-0
lines changed

11 files changed

+483
-0
lines changed

requirements-native.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ lxml==5.1.0
44
MarkupSafe==2.1.5
55
pyahocorasick==2.1.0
66
PyYAML==6.0.1
7+
regex==2022.8.17

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ cryptography==42.0.5
1717
debian-inspector==31.1.0
1818
dockerfile-parse==1.2.0
1919
dparse2==0.7.0
20+
deprecated == 1.2.18
2021
extractcode==31.0.0
2122
extractcode-7z==16.5.210531
2223
extractcode-libarchive==3.5.1.210531
@@ -40,6 +41,7 @@ lxml==5.1.0
4041
MarkupSafe==2.1.5
4142
more-itertools==8.13.0
4243
normality==2.3.3
44+
oelint_parser==8.1.0
4345
packageurl-python==0.15.0
4446
packaging==24.1
4547
packvers==21.5
@@ -61,6 +63,7 @@ pyparsing==3.0.9
6163
pytz==2022.1
6264
PyYAML==6.0.1
6365
rdflib==6.2.0
66+
regex == 2024.11.6
6467
requests==2.31.0
6568
saneyaml==0.6.0
6669
semantic-version==2.8.5

setup-mini.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ install_requires =
8787
license_expression >= 30.4.1
8888
lxml >= 4.9.2
8989
MarkupSafe >= 2.1.2
90+
oelint_parser >= 8.0.0
9091
packageurl_python >= 0.9.0
9192
packvers >= 21.0.0
9293
# use temp advanced patched release

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ install_requires =
8787
license_expression >= 30.4.1
8888
lxml >= 4.9.2
8989
MarkupSafe >= 2.1.2
90+
oelint_parser >= 8.0.0
9091
packageurl_python >= 0.9.0
9192
packvers >= 21.0.0
9293
# use temp advanced patched release

src/packagedcode/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from commoncode.system import on_linux
1111
from packagedcode import about
1212
from packagedcode import alpine
13+
from packagedcode import bitbake
1314
from packagedcode import bower
1415
from packagedcode import build
1516
from packagedcode import build_gradle
@@ -55,6 +56,8 @@
5556

5657
bower.BowerJsonHandler,
5758

59+
bitbake.BitbakeBbManifestHandler,
60+
5861
build_gradle.BuildGradleHandler,
5962

6063
build.AutotoolsConfigureHandler,

src/packagedcode/bitbake.py

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# ScanCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6+
# See https://github.com/nexB/scancode-toolkit for support or download.
7+
# See https://aboutcode.org for more information about nexB OSS projects.
8+
#
9+
10+
import logging
11+
import re
12+
13+
from oelint_parser.cls_stash import Stash
14+
from packageurl import PackageURL
15+
16+
from packagedcode import models
17+
18+
TRACE = True
19+
20+
logger = logging.getLogger(__name__)
21+
22+
if TRACE:
23+
import sys
24+
logging.basicConfig(stream=sys.stdout)
25+
logger.setLevel(logging.DEBUG)
26+
27+
28+
class BitbakeBbManifestHandler(models.DatafileHandler):
29+
datasource_id = 'bitbake_bb_recipe'
30+
# note that there are .bbappend, .bbclass and bitbake.conf files.
31+
path_patterns = ('*.bb',)
32+
default_package_type = 'bitbake'
33+
description = 'BitBake bb recipe manifest'
34+
documentation_url = 'https://docs.yoctoproject.org/bitbake/bitbake-user-manual/bitbake-user-manual-metadata.html'
35+
36+
@classmethod
37+
def parse(cls, location):
38+
39+
oestash = Stash(quiet=True)
40+
41+
# add any bitbake like-file
42+
# TODO: may be we should handle the bbclass and bbappend here?
43+
oestash.AddFile(location)
44+
45+
# Resolves proper cross file dependencies
46+
oestash.Finalize()
47+
48+
# collect all variables of interest.
49+
# TODO: we should not get list values. Instead plain strings
50+
data = {
51+
k: ' '.join(v) if isinstance(v, (list, tuple)) else v
52+
for k, v in oestash.ExpandVar(filename=location).items()
53+
if v
54+
}
55+
name = data.get('PN')
56+
version = data.get('PV')
57+
description = data.get('DESCRIPTION')
58+
homepage_url = data.get('HOMEPAGE')
59+
download_url = data.get('PREMIRRORS')
60+
extracted_license_statement = data.get('LICENSE')
61+
62+
# The item.VarName for SRC_URI[*] from the parser are SRC_URI
63+
# Therefore, I cannot differentiate md5, sha1, or src file location reference
64+
# See: https://github.com/priv-kweihmann/oelint-parser/issues/3
65+
sha1 = data.get('SRC_URI[sha1sum]')
66+
md5 = data.get('SRC_URI[md5sum]')
67+
sha256 = data.get('SRC_URI[sha256sum]')
68+
sha512 = data.get('SRC_URI[sha512sum]')
69+
70+
dependencies = []
71+
72+
# Build deps: this is a list of plain BB recipes names
73+
# https://docs.yoctoproject.org/bitbake/bitbake-user-manual/bitbake-user-manual-ref-variables.html#term-DEPENDS
74+
build_deps = data.get('DEPENDS', '').split()
75+
for build_dep in build_deps:
76+
dep_purl = PackageURL(
77+
type=cls.default_package_type,
78+
name=build_dep,
79+
).to_string()
80+
81+
dependency = models.DependentPackage(
82+
purl=dep_purl,
83+
extracted_requirement=build_dep,
84+
scope='build',
85+
is_runtime=False,
86+
is_optional=True,
87+
is_pinned=False,
88+
is_direct=True,
89+
)
90+
dependencies.append(dependency)
91+
92+
# Runtime deps:this is a list of Package names with an optional (=> 12) version constraint
93+
# https://docs.yoctoproject.org/bitbake/bitbake-user-manual/bitbake-user-manual-ref-variables.html#term-RDEPENDS
94+
# FIXME: There are some fields such as "RDEPENDS_${PN}" so these may not be correct in all cases
95+
for key, value in data.items():
96+
if not key.startswith('RDEPENDS'):
97+
continue
98+
if not value:
99+
continue
100+
for name, constraint in get_bitbake_deps(dependencies=value):
101+
if TRACE:
102+
logger.debug(f'RDEPENDS: name={name}, constraint={constraint}')
103+
dep_purl = PackageURL(
104+
type=cls.default_package_type,
105+
name=name,
106+
).to_string()
107+
108+
extracted_requirement = name
109+
if constraint:
110+
extracted_requirement += f' ({constraint})'
111+
112+
dependency = models.DependentPackage(
113+
purl=dep_purl,
114+
extracted_requirement=extracted_requirement,
115+
scope='install',
116+
is_runtime=True,
117+
is_optional=False,
118+
is_pinned=False,
119+
is_direct=True,
120+
)
121+
122+
dependencies.append(dependency)
123+
124+
yield models.PackageData(
125+
datasource_id=cls.datasource_id,
126+
type=cls.default_package_type,
127+
name=name,
128+
version=version,
129+
description=description,
130+
homepage_url=homepage_url,
131+
download_url=download_url,
132+
sha1=sha1,
133+
md5=md5,
134+
sha256=sha256,
135+
sha512=sha512,
136+
extracted_license_statement=extracted_license_statement,
137+
dependencies=dependencies,
138+
)
139+
140+
@classmethod
141+
def assign_package_to_resources(cls, package, resource, codebase, package_adder):
142+
return models.DatafileHandler.assign_package_to_parent_tree(package, resource, codebase, package_adder)
143+
144+
145+
def get_bitbake_deps(dependencies):
146+
"""
147+
Return a list of tuple of (name, version constraint) given a BitBake
148+
dependencies string. "version constraint" can be None.
149+
150+
See https://docs.yoctoproject.org/ref-manual/variables.html?#term-RDEPENDS
151+
For example:
152+
>>> expected = [('ABC', None), ('abcd', '=>12312'), ('defg', None)]
153+
>>> result = get_bitbake_deps(" ABC abcd (= > 12312) defg ")
154+
>>> assert result == expected, result
155+
>>> expected = [('grub', '==12.23'), ('parted', None), ('e2fsprogs-mke2fs', None)]
156+
>>> result = get_bitbake_deps("grub (== 12.23) parted e2fsprogs-mke2fs")
157+
>>> assert result == expected, result
158+
"""
159+
return [split_name_constraint(nc) for nc in split_deps(dependencies)]
160+
161+
162+
def split_name_constraint(dependency):
163+
"""
164+
Return a tuple (name, version constraint) strings given a name (version
165+
constraint) BitBake dependency string.
166+
See https://docs.yoctoproject.org/ref-manual/variables.html?#term-RDEPENDS
167+
For example:
168+
>>> assert split_name_constraint(" abcd ( = 12312 ) ") == ("abcd", "=12312",)
169+
>>> assert split_name_constraint("abcd ") == ("abcd", None)
170+
"""
171+
no_spaces = dependency.replace(' ', '')
172+
if '(' in no_spaces:
173+
name, _, constraint = no_spaces.partition('(')
174+
constraint = constraint.rstrip(')')
175+
return name, constraint
176+
return no_spaces, None
177+
178+
179+
def split_deps(dependencies):
180+
"""
181+
Return a list of name (version constraint) strings given a BitBake
182+
dependencies string.
183+
184+
See https://docs.yoctoproject.org/ref-manual/variables.html?#term-RDEPENDS
185+
For example:
186+
>>> expected = ['ABC', 'abcd (= > 12312)', 'defg', 'foo', 'bar']
187+
>>> result = split_deps(" ABC abcd (= > 12312) defg foo bar ")
188+
>>> assert result == expected, result
189+
"""
190+
normalized_spaces = ' '.join(dependencies.split())
191+
name = r'\w[\w\d_-]+'
192+
version_constraint = r'\([<>= ]+[^<>= ]+\s?\)'
193+
splitter = re.compile(fr'({name}\s?(?:{version_constraint})?)').findall
194+
return [s.strip() for s in splitter(normalized_spaces)]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
SUMMARY = "Live image install script with a second rootfs/kernel"
2+
LICENSE = "MIT"
3+
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
4+
SRC_URI = "file://init-install-testfs.sh"
5+
DEPENDS = "do_this and that"
6+
7+
RDEPENDS_${PN} = "grub (== 12.23) parted e2fsprogs-mke2fs"
8+
9+
S = "${WORKDIR}"
10+
11+
do_install() {
12+
install -m 0755 ${WORKDIR}/init-install-testfs.sh ${D}/install.sh
13+
}
14+
15+
INHIBIT_DEFAULT_DEPS = "1"
16+
FILES_${PN} = " /install.sh "
17+
COMPATIBLE_HOST = "(i.86|x86_64).*-linux"

0 commit comments

Comments
 (0)