Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/513+514 #519

Merged
merged 4 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ Rules marked with **[S]** can have multiple sub-IDs
* oelint.var.bbclassextend - Use BBCLASSEXTEND when possible
* oelint.var.filesoverride - FILES:*(FILES_*) variables should not be overridden
* oelint.var.improperinherit - Warn about improperly named inherits
* oelint.var.inherit - Check the correct usage of inherit and inherit_defer ('scarthgap' release and newer)
* oelint.var.inheritdevtool - inherit_defer is recommended for native and nativesdk class **[S]**
* oelint.var.inherit - Check the correct usage of inherit and inherit_defer (scarthgap+)
* oelint.var.inheritdevtool - inherit_defer is recommended for native and nativesdk class **[S]** (scarthgap+)
* oelint.var.licenseremotefile - License shall be a file in remote source not a local file
* oelint.var.licensesdpx - Check for correct SPDX syntax in licenses
* oelint.var.mandatoryvar - Check for mandatory variables **[S]**
Expand All @@ -178,6 +178,7 @@ Rules marked with **[S]** can have multiple sub-IDs
* oelint.vars.doublemodify - Multiple modifiers of append/prepend/remove/+= found in one operation
* oelint.vars.downloadfilename - Fetcher does create a download artifact without 'PV' in the filename
* oelint.vars.duplicate - No duplicates in DEPENDS and RDEPENDS
* oelint.vars.dusageinpkgfuncs - use \$D instead of \$\{D\} in pkg functions **[F]**
* oelint.vars.fileextrapaths - 'FILESEXTRAPATHS' shouldn't be used in a bb file
* oelint.vars.fileextrapathsop - 'FILESEXTRAPATHS' should only be used in combination with ' := '
* oelint.vars.filessetting - unnecessary FILES settings
Expand All @@ -198,6 +199,7 @@ Rules marked with **[S]** can have multiple sub-IDs
* oelint.vars.pkgspecific - Variable is package-specific, but isn't set in that way **[S]**
* oelint.vars.pnbpnusage - \$\{BPN\} should be used instead of \$\{PN\} **[F]**
* oelint.vars.pnusagediscouraged - Variable shouldn't contain \$\{PN\} or \$\{BPN\}
* oelint.vars.pythonpnusage - python3 should be used instead of \$\{PYTHON_PN\} **[F]** (scarthgap+)
* oelint.vars.sectionlowercase - SECTION should be lowercase only **[F]**
* oelint.vars.spacesassignment - ' = ' should be correct variable assignment
* oelint.vars.specific - Variable is specific to an unknown identifier
Expand Down
2 changes: 2 additions & 0 deletions oelint_adv/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ def rule_applicable(rule):
rules='\n\t'.join(sorted(_loaded_ids))))
issues = []
groups = group_files(args.files)
if not any(groups):
return []
with mp.Pool(processes=min(args.jobs, len(groups))) as pool:
try:
issues = flatten(pool.map(partial(group_run, quiet=args.quiet, fix=args.fix,
Expand Down
44 changes: 44 additions & 0 deletions oelint_adv/rule_base/rule_var_pkgfunc_dusage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from typing import List, Tuple

from oelint_parser.cls_item import Function
from oelint_parser.cls_stash import Stash

from oelint_adv.cls_rule import Rule


class VarDUsageInPkgfunc(Rule):
def __init__(self) -> None:
super().__init__(id='oelint.vars.dusageinpkgfuncs',
severity='error',
message='Use $D instead of ${{D}} in {func}')

def __getMatches(self, _file: str, stash: Stash) -> List[Function]:
res = []
items: List[Function] = stash.GetItemsFor(filename=_file,
classifier=Function.CLASSIFIER,
attribute=Function.ATTR_FUNCNAME,
attributeValue=[
'pkg_preinst',
'pkg_postinst',
'pkg_postrm',
'pkg_prerm',
],
)
for i in items:
if '${D}' in i.FuncBodyRaw:
res.append(i)
return res

def check(self, _file: str, stash: Stash) -> List[Tuple[str, int, str]]:
res = []
for i in self.__getMatches(_file, stash):
res += self.finding(i.Origin, i.InFileLine, override_msg=self.Msg.format(func=i.FuncName))
return res

def fix(self, _file: str, stash: Stash) -> List[str]:
res = []
for i in self.__getMatches(_file, stash):
i.RealRaw = i.RealRaw.replace('${D}', '$D')
i.Raw = i.Raw.replace('${D}', '$D')
res.append(_file)
return res
52 changes: 52 additions & 0 deletions oelint_adv/rule_base/rule_var_python_pn_usage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from typing import List, Tuple

from oelint_parser.cls_item import Function, Item, PythonBlock, Variable
from oelint_parser.cls_stash import Stash

from oelint_adv.cls_rule import Rule


class VarPythonPnUsage(Rule):
def __init__(self) -> None:
super().__init__(id='oelint.vars.pythonpnusage',
severity='info',
message='python3 should be used instead of ${PYTHON_PN}',
valid_from_release='scarthgap')

def __getMatches(self, _file: str, stash: Stash) -> List[Tuple[Item, List[str]]]:
res = []
items: List[Item] = stash.GetItemsFor(filename=_file,
classifier=[
Variable.CLASSIFIER,
Function.CLASSIFIER,
PythonBlock.CLASSIFIER,
])
for i in items:
if i.Origin.endswith('.bbclass'):
continue
if isinstance(i, PythonBlock):
needles = ['${PYTHON_PN}', 'd.getVar("PYTHON_PN")', 'd.getVar(\'PYTHON_PN\')']
elif isinstance(i, (Function, Variable)):
needles = ['${PYTHON_PN}']
else:
needles = [] # pragma: no cover
if any(x in i.Raw for x in needles):
res.append((i, needles))
return res

def check(self, _file: str, stash: Stash) -> List[Tuple[str, int, str]]:
res = []
for i in self.__getMatches(_file, stash):
item, _ = i
res += self.finding(item.Origin, item.InFileLine)
return res

def fix(self, _file: str, stash: Stash) -> List[str]:
res = []
for i in self.__getMatches(_file, stash):
item, needles = i
for needle in needles:
item.RealRaw = item.RealRaw.replace(needle, 'python3')
item.Raw = item.Raw.replace(needle, 'python3')
res.append(_file)
return res
172 changes: 172 additions & 0 deletions tests/test_class_oelint_vars_dusagepkgfunc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import pytest # noqa: I900

from .base import TestBaseClass


class TestClassOelintVarsDUsagePkgFunc(TestBaseClass):

@pytest.mark.parametrize('id_', ['oelint.vars.dusageinpkgfuncs'])
@pytest.mark.parametrize('occurrence', [1])
@pytest.mark.parametrize('input_',
[
{
'oelint_adv_test.bb':
'''
pkg_preinst:${PN} () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_postinst:${PN} () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_prerm:${PN} () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_postrm:${PN} () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
],
)
def test_bad(self, input_, id_, occurrence):
self.check_for_id(self._create_args(input_), id_, occurrence)

@pytest.mark.parametrize('id_', ['oelint.vars.dusageinpkgfuncs'])
@pytest.mark.parametrize('input_',
[
{
'oelint_adv_test.bb':
'''
pkg_preinst:${PN} () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_postinst:${PN} () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_prerm:${PN} () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_postrm:${PN} () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
],
)
def test_fix(self, input_, id_):
self.fix_and_check(self._create_args_fix(input_), id_)

@pytest.mark.parametrize('id_', ['oelint.vars.dusageinpkgfuncs'])
@pytest.mark.parametrize('occurrence', [0])
@pytest.mark.parametrize('input_',
[
{
'oelint_adv_test.bb':
'''
pkg_preinst:${PN} () {
if [ -n "$D" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_postinst:${PN} () {
if [ -n "$D" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_prerm:${PN} () {
if [ -n "$D" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_postrm:${PN} () {
if [ -n "$D" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
pkg_postrm:${PN} () {
if [ -n "${Z}" ]; then
echo "Foo"
fi
}
''',
},
{
'oelint_adv_test.bb':
'''
do_install () {
if [ -n "${D}" ]; then
echo "Foo"
fi
}
''',
},
],
)
def test_good(self, input_, id_, occurrence):
self.check_for_id(self._create_args(input_), id_, occurrence)
Loading