commit: bad313667aa111639f9c5801d6f10420968ac2b9 Author: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> AuthorDate: Thu Nov 3 17:43:47 2022 +0000 Commit: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> CommitDate: Tue Nov 8 18:59:00 2022 +0000 URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=bad31366
NonPosixHeadTailUsage: new check New warning for non-POSIX compliant head or tail without -n. Closes: https://bugs.gentoo.org/558360 Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org> src/pkgcheck/checks/codingstyle.py | 46 ++++++++++++++++++++++ .../NonPosixHeadTailUsage/expected.json | 5 +++ .../NonPosixCheck/NonPosixHeadTailUsage/fix.patch | 26 ++++++++++++ .../NonPosixHeadTailUsage-0.ebuild | 10 +++++ .../NonPosixHeadTailUsage-1.ebuild | 11 ++++++ 5 files changed, 98 insertions(+) diff --git a/src/pkgcheck/checks/codingstyle.py b/src/pkgcheck/checks/codingstyle.py index 30e7f9f9..954ef09d 100644 --- a/src/pkgcheck/checks/codingstyle.py +++ b/src/pkgcheck/checks/codingstyle.py @@ -1170,3 +1170,49 @@ class DoCompressedFilesCheck(Check): lineno, _ = arg.start_point if arg_name.endswith(self.compresion_extentions): yield self.functions[call_name](call_name, lineno=lineno+1, line=arg_name, pkg=pkg) + + +class NonPosixHeadTailUsage(results.LineResult, results.Warning): + """Using of non-POSIX compliant ``head`` or ``tail``. + + The numeric argument to ``head`` or ``tail`` without ``-n`` (for example + ``head -10``) is deprecated and not POSIX compliant. To fix, prepand ``-n`` + before the number [#]_. + + .. [#] https://devmanual.gentoo.org/tools-reference/head-and-tail/index.html + """ + def __init__(self, command, **kwargs): + super().__init__(**kwargs) + self.command = command + + @property + def desc(self): + return f'line {self.lineno}: non-posix usage of {self.command!r}: {self.line!r}' + + +class NonPosixCheck(Check): + """Scan ebuild for non-posix usage, code which might be not portable.""" + + _source = sources.EbuildParseRepoSource + known_results = frozenset([NonPosixHeadTailUsage]) + + def __init__(self, options, **kwargs): + super().__init__(options, **kwargs) + self.re_head_tail = re.compile(r'[+-]\d+') + + def check_head_tail(self, pkg, call_node, call_name): + prev_arg = '' + for arg in map(pkg.node_str, call_node.children[1:]): + if (self.re_head_tail.match(arg) and + not (prev_arg.startswith('-') and prev_arg.endswith(('n', 'c')))): + lineno, _ = call_node.start_point + yield NonPosixHeadTailUsage(f'{call_name} {arg}', + lineno=lineno+1, line=pkg.node_str(call_node), pkg=pkg) + break + prev_arg = arg + + def feed(self, pkg): + for call_node, _ in bash.cmd_query.captures(pkg.tree.root_node): + call_name = pkg.node_str(call_node.child_by_field_name('name')) + if call_name in ('head', 'tail'): + yield from self.check_head_tail(pkg, call_node, call_name) diff --git a/testdata/data/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/expected.json b/testdata/data/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/expected.json new file mode 100644 index 00000000..daed2c67 --- /dev/null +++ b/testdata/data/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/expected.json @@ -0,0 +1,5 @@ +{"__class__": "NonPosixHeadTailUsage", "category": "NonPosixCheck", "package": "NonPosixHeadTailUsage", "version": "0", "line": "head -1 file", "lineno": 7, "command": "head -1"} +{"__class__": "NonPosixHeadTailUsage", "category": "NonPosixCheck", "package": "NonPosixHeadTailUsage", "version": "0", "line": "head -q file -1", "lineno": 8, "command": "head -1"} +{"__class__": "NonPosixHeadTailUsage", "category": "NonPosixCheck", "package": "NonPosixHeadTailUsage", "version": "1", "line": "tail -1 file", "lineno": 7, "command": "tail -1"} +{"__class__": "NonPosixHeadTailUsage", "category": "NonPosixCheck", "package": "NonPosixHeadTailUsage", "version": "1", "line": "tail -q file -1", "lineno": 8, "command": "tail -1"} +{"__class__": "NonPosixHeadTailUsage", "category": "NonPosixCheck", "package": "NonPosixHeadTailUsage", "version": "1", "line": "tail -qn file +1", "lineno": 9, "command": "tail +1"} diff --git a/testdata/data/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/fix.patch b/testdata/data/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/fix.patch new file mode 100644 index 00000000..c01e9028 --- /dev/null +++ b/testdata/data/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/fix.patch @@ -0,0 +1,26 @@ +--- standalone/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-0.ebuild ++++ fixed/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-0.ebuild +@@ -4,7 +4,7 @@ SLOT="0" + LICENSE="BSD" + + src_prepare() { +- head -1 file > another || die +- head -q file -1 > another || die ++ head -n -1 file > another || die ++ head -qn 1 file > another || die + default + } +--- standalone/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-1.ebuild ++++ fixed/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-1.ebuild +@@ -4,8 +4,8 @@ SLOT="0" + LICENSE="BSD" + + src_prepare() { +- tail -1 file > another || die +- tail -q file -1 > another || die +- tail -qn file +1 > another || die ++ tail -n 1 file > another || die ++ tail -q file -c 1 > another || die ++ tail file -qn +1 > another || die + default + } diff --git a/testdata/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-0.ebuild b/testdata/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-0.ebuild new file mode 100644 index 00000000..6ee3b8fc --- /dev/null +++ b/testdata/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-0.ebuild @@ -0,0 +1,10 @@ +DESCRIPTION="Ebuild with non posix head usage" +HOMEPAGE="https://github.com/pkgcore/pkgcheck" +SLOT="0" +LICENSE="BSD" + +src_prepare() { + head -1 file > another || die + head -q file -1 > another || die + default +} diff --git a/testdata/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-1.ebuild b/testdata/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-1.ebuild new file mode 100644 index 00000000..6e926ae8 --- /dev/null +++ b/testdata/repos/standalone/NonPosixCheck/NonPosixHeadTailUsage/NonPosixHeadTailUsage-1.ebuild @@ -0,0 +1,11 @@ +DESCRIPTION="Ebuild with non posix head usage" +HOMEPAGE="https://github.com/pkgcore/pkgcheck" +SLOT="0" +LICENSE="BSD" + +src_prepare() { + tail -1 file > another || die + tail -q file -1 > another || die + tail -qn file +1 > another || die + default +}
