This repository was archived by the owner on Apr 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Add unversioned shebangs check #30
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| import libarchive | ||
|
|
||
| from .common import log, write_to_artifact | ||
|
|
||
| MESSAGE = """These RPMs contain problematic shebang in some of the scripts: | ||
| {} | ||
| This is discouraged and should be avoided. Please check the shebangs | ||
| and use either `#!/usr/bin/python2` or `#!/usr/bin/python3`. | ||
| """ | ||
|
|
||
| # TODO: update to real doc relevant to shebangs | ||
| INFO_URL = ' https://pagure.io/packaging-committee/issue/698' | ||
|
|
||
| FORBIDDEN_SHEBANGS = ['#!/usr/bin/python', '#!/usr/bin/env python'] | ||
|
|
||
|
|
||
| def matches(line, query): | ||
| """Both arguments must be of a type bytes""" | ||
| return line == query or line.startswith(query + b' ') | ||
|
|
||
|
|
||
| def get_problematic_files(archive, query): | ||
| """Search for the files inside archive with the first line | ||
| matching given query. Some of the files can contain data, which | ||
| are not in the plain text format. Bytes are read from the file and | ||
| the shebang query has to be of the same type. | ||
| """ | ||
| problematic = set() | ||
| with libarchive.file_reader(archive) as a: | ||
| for entry in a: | ||
| try: | ||
| first_line = next(entry.get_blocks(), '').splitlines()[0] | ||
| except IndexError: | ||
| continue # file is empty | ||
| if matches(first_line, query.encode()): | ||
| problematic.add(entry.pathname.lstrip('.')) | ||
|
|
||
| return problematic | ||
|
|
||
|
|
||
| def shebang_to_require(shebang): | ||
| """Convert shebang to the format of requirement.""" | ||
| return shebang.split()[0][2:].encode() | ||
|
|
||
|
|
||
| def get_scripts_summary(package): | ||
| """Collect problematic scripts data for given RPM package. | ||
| Content of archive is processed only if package requires | ||
| unversioned python binary or env. | ||
| """ | ||
| scripts_summary = {} | ||
|
|
||
| for shebang in FORBIDDEN_SHEBANGS: | ||
| if shebang_to_require(shebang) in package.require_names: | ||
| scripts_summary[shebang] = get_problematic_files( | ||
| package.path, shebang) | ||
| return scripts_summary | ||
|
|
||
|
|
||
| def task_unversioned_shebangs(packages, koji_build, artifact): | ||
| """Check if some of the binaries contains '/usr/bin/python' | ||
| shebang or '/usr/bin/env python' shebang. | ||
| """ | ||
| # libtaskotron is not available on Python 3, so we do it inside | ||
| # to make the above functions testable anyway | ||
| from libtaskotron import check | ||
|
|
||
| outcome = 'PASSED' | ||
|
|
||
| problem_rpms = {} | ||
| shebang_message = '' | ||
|
|
||
| for package in packages: | ||
| log.debug('Checking shebangs of {}'.format(package.filename)) | ||
| problem_rpms[package.nvr] = get_scripts_summary(package) | ||
|
|
||
| for package, pkg_summary in problem_rpms.items(): | ||
| for shebang, scripts in pkg_summary.items(): | ||
| outcome = 'FAILED' | ||
| shebang_message += \ | ||
| '{}\n * Scripts containing `{}` shebang:\n {}'.format( | ||
| package, shebang, '\n '.join(sorted(scripts))) | ||
|
|
||
| detail = check.CheckDetail( | ||
| checkname='python-versions.unversioned_shebangs', | ||
| item=koji_build, | ||
| report_type=check.ReportType.KOJI_BUILD, | ||
| outcome=outcome) | ||
|
|
||
| if outcome == 'FAILED': | ||
| detail.artifact = artifact | ||
| write_to_artifact(artifact, MESSAGE.format(shebang_message), INFO_URL) | ||
| else: | ||
| shebang_message = 'No problems found.' | ||
|
|
||
| log.info('python-versions.unversioned_shebangs {} for {}. {}'.format( | ||
| outcome, koji_build, shebang_message)) | ||
|
|
||
| return detail | ||
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import pytest | ||
|
|
||
| from taskotron_python_versions.unversioned_shebangs import ( | ||
| matches, | ||
| get_problematic_files, | ||
| shebang_to_require, | ||
| get_scripts_summary, | ||
| ) | ||
| from .common import gpkg, gpkg_path | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(('line', 'query', 'expected'), ( | ||
| (b'#!/usr/bin/python', b'#!/usr/bin/python', True), | ||
| (b'#!/usr/bin/python ', b'#!/usr/bin/python', True), | ||
| (b'#!/usr/bin/python -I', b'#!/usr/bin/python', True), | ||
| (b'#!/usr/bin/python #comment', b'#!/usr/bin/python', True), | ||
| (b'#!/usr/bin/python3', b'#!/usr/bin/python', False), | ||
| (b'#!/usr/bin/python2', b'#!/usr/bin/python', False), | ||
| (b'#!/usr/bin/env python', b'#!/usr/bin/env python', True), | ||
| (b'#!/usr/bin/env python -I', b'#!/usr/bin/env python', True), | ||
| (b'#!/usr/bin/env python3', b'#!/usr/bin/env python', False), | ||
| (b'#!/usr/bin/env python2', b'#!/usr/bin/env python', False), | ||
| (b'#!/usr/bin/env perl', b'#!/usr/bin/env python', False), | ||
| )) | ||
| def test_matches(line, query, expected): | ||
| assert matches(line, query) == expected | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(('archive', 'query', 'expected'), ( | ||
| ('tracer*', | ||
| '#!/usr/bin/python', {'/usr/bin/tracer'}), | ||
| ('python3-django*', '#!/usr/bin/env python', | ||
| {'/usr/lib/python3.6/site-packages/django/bin/django-admin.py', | ||
| ('/usr/lib/python3.6/site-packages/' | ||
| 'django/conf/project_template/manage.py-tpl')}), | ||
| ('python3-django*', '#!/usr/bin/python', set()), | ||
| ('pyserial*', '#!/usr/bin/python', set()), | ||
| )) | ||
| def test_get_problematic_files(archive, query, expected): | ||
| assert get_problematic_files(gpkg_path(archive), query) == expected | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(('shebang', 'expected'), ( | ||
| ("#!/foo", b"/foo"), | ||
| ("#!/usr/bin/python", b"/usr/bin/python"), | ||
| ("#!/usr/bin/env python", b"/usr/bin/env"), | ||
| )) | ||
| def test_shebang_to_require(shebang, expected): | ||
| assert shebang_to_require(shebang) == expected | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(('glob', 'expected'), ( | ||
| ('tracer*', | ||
| {'#!/usr/bin/python': {'/usr/bin/tracer'}}), | ||
| ('python3-django*', | ||
| {'#!/usr/bin/env python': | ||
| {'/usr/lib/python3.6/site-packages/django/bin/django-admin.py', | ||
| ('/usr/lib/python3.6/site-packages/' | ||
| 'django/conf/project_template/manage.py-tpl')}}), | ||
| ('pyserial*', {}), | ||
| )) | ||
| def test_get_scripts_summary(glob, expected): | ||
| assert get_scripts_summary(gpkg(glob)) == expected |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment explaining that we are reading the bytes of the file because we don't know if it's "plaintext", hence we'll need to check the shebang using bytes as well.