diff --git a/Makefile b/Makefile index a6aca645e4..8fe34d072f 100644 --- a/Makefile +++ b/Makefile @@ -251,6 +251,7 @@ flake8: requirements .flake8 @echo @echo "==================== flake ====================" @echo + . $(VIRTUALENV_DIR)/bin/activate; cd ./lint-configs/python/flake8_plugins; python setup.py develop . $(VIRTUALENV_DIR)/bin/activate; flake8 --config ./lint-configs/python/.flake8 $(COMPONENTS) . $(VIRTUALENV_DIR)/bin/activate; flake8 --config ./lint-configs/python/.flake8 $(COMPONENTS_RUNNERS) . $(VIRTUALENV_DIR)/bin/activate; flake8 --config ./lint-configs/python/.flake8 contrib/packs/actions/ diff --git a/lint-configs/.gitignore b/lint-configs/.gitignore new file mode 100644 index 0000000000..a044288f90 --- /dev/null +++ b/lint-configs/.gitignore @@ -0,0 +1,63 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Virtual Environments +.venv + +# Temporary Files +*.swp + +# Visual Studio Code +.vscode/ diff --git a/lint-configs/python/.flake8 b/lint-configs/python/.flake8 index aeb7b4a604..f3cc01b319 100644 --- a/lint-configs/python/.flake8 +++ b/lint-configs/python/.flake8 @@ -1,19 +1,18 @@ [flake8] max-line-length = 100 -ignore = - E128,E402,E722,W504, - H101,H104,H105,H106,H107,H108,H109, - H201,H202,H203,H204,H205,H206,H207,H208,H209,H234,H238, - H301,H302,H303,H304,H305,H306,H307,H308,H309, - H401,H402,H403,H404,H405,H406,H407,H408,H409, - H501,H502,H503,H504,H505,H506,H507,H508,H509, - H601,H602,H603,H604,H605,H606,H607,H608,H609, - H701,H702,H703,H704,H705,H706,H707,H708,H709, - H801,H802,H803,H804,H805,H806,H807,H808,H809, - H901,H902,H903,H904,H905,H906,H907,H908,H909 +# L102 - apache license header +enable-extensions = L101,L102 +ignore = E128,E402,E722,W504 exclude=*.egg/*,build,dist # Configuration for flake8-copyright extension copyright-check = True copyright-min-file-size = 1 -select = E,F,W,C + +# Settings for flake8-license +license-type = apache + +# NOTE: This requires flake8 >= 3.0.0 to work correctly. +# If old version is used (< 3.0.0), it will select all the errors and it wont ignore ones +# listed above as part of ignore list +select = E,F,W,C,L diff --git a/lint-configs/python/.flake8-oss b/lint-configs/python/.flake8-oss new file mode 120000 index 0000000000..75610e8489 --- /dev/null +++ b/lint-configs/python/.flake8-oss @@ -0,0 +1 @@ +.flake8 \ No newline at end of file diff --git a/lint-configs/python/.flake8-proprietary b/lint-configs/python/.flake8-proprietary new file mode 100644 index 0000000000..afb1456601 --- /dev/null +++ b/lint-configs/python/.flake8-proprietary @@ -0,0 +1,17 @@ +[flake8] +max-line-length = 100 +# L101 - proprietary license header +enable-extensions = L101,L102 +ignore = E128,E402,E722,W504 +exclude=*.egg/*,build,dist + +# Configuration for flake8-copyright extension +copyright-check = True +copyright-min-file-size = 1 + +license-type = proprietary + +# NOTE: This requires flake8 >= 3.0.0 to work correctly. +# If old version is used (< 3.0.0), it will select all the errors and it wont ignore ones +# listed above as part of ignore list +select = E,F,W,C,L diff --git a/lint-configs/python/flake8_plugins/flake8_plugins/__init__.py b/lint-configs/python/flake8_plugins/flake8_plugins/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lint-configs/python/flake8_plugins/flake8_plugins/license_rules.py b/lint-configs/python/flake8_plugins/flake8_plugins/license_rules.py new file mode 100644 index 0000000000..c9b6bdae18 --- /dev/null +++ b/lint-configs/python/flake8_plugins/flake8_plugins/license_rules.py @@ -0,0 +1,116 @@ +# Copyright 2019 Extreme Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import optparse + + +APACHE_20_LICENSE = """ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + +PROPRIETARY_LICENSE = """ +# Unauthorized copying of this file, via any medium is strictly +# prohibited. Proprietary and confidential. See the LICENSE file +# included with this work for details. +""" + +APACHE_20_LICENSE = APACHE_20_LICENSE.strip('\n') +PROPRIETARY_LICENSE = PROPRIETARY_LICENSE.strip('\n') + +LICENSE_TYPES = { + 'proprietary': PROPRIETARY_LICENSE, + 'apache': APACHE_20_LICENSE +} + +ERROR_MESSAGES = { + 'proprietary': 'L101 Proprietary license header not found', + 'apache': 'L102 Apache 2.0 license header not found' +} + + +# Temporary shim for flake8 2.x --> 3.x transition +# http://flake8.pycqa.org/en/latest/plugin-development/cross-compatibility.html#option-handling-on-flake8-2-and-3 +def register_opt(parser, *args, **kwargs): + try: + # Flake8 3.x registration + parser.add_option(*args, **kwargs) + except (optparse.OptionError, TypeError): + # Flake8 2.x registration + parse_from_config = kwargs.pop('parse_from_config', False) + kwargs.pop('comma_separated_list', False) + kwargs.pop('normalize_paths', False) + parser.add_option(*args, **kwargs) + if parse_from_config: + parser.config_options.append(args[-1].lstrip('-')) + + +class LicenseChecker(object): + name = 'flake8_license' + version = '0.1.0' + off_by_default = False + + def __init__(self, tree, filename): + self.tree = tree + self.filename = filename + + @classmethod + def add_options(cls, parser): + register_opt( + parser, + '--license-type', + type='choice', + choices=['proprietary', 'apache'], + default='apache', + action='store', + parse_from_config=True, + help='Checks for specific type of license header.' + ) + + register_opt( + parser, + '--license-min-file-size', + type='int', + default=1, + action='store', + parse_from_config=True, + help='Minimum number of characters in a file before requiring a license header.' + ) + + @classmethod + def parse_options(cls, options): + cls.license_type = options.license_type + cls.min_file_size = options.license_min_file_size + + def run(self): + """Check for license header given license type. + L101 Proprietary license header not found + L102 Apache 2.0 license header not found + """ + with open(self.filename, 'r') as f: + content = f.read() + + if len(content) >= self.min_file_size and LICENSE_TYPES[self.license_type] not in content: + yield 1, 1, ERROR_MESSAGES[self.license_type], type(self) diff --git a/lint-configs/python/flake8_plugins/setup.py b/lint-configs/python/flake8_plugins/setup.py new file mode 100644 index 0000000000..8213cef564 --- /dev/null +++ b/lint-configs/python/flake8_plugins/setup.py @@ -0,0 +1,49 @@ +# Copyright 2019 Extreme Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from setuptools import setup + +REQUIRES = [ + 'flake8' +] + +setup( + name='st2_flake8_plugins', + version='0.1.0', + author='StackStorm', + author_email='info@stackstorm.com', + url='https://www.stackstorm.com', + packages=[ + 'flake8_plugins' + ], + install_requires=REQUIRES, + license='Apache License (2.0)', + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6' + ], + entry_points={ + 'flake8.extension': [ + 'L = flake8_plugins.license_rules:LicenseChecker', + ] + } +) diff --git a/test-requirements.txt b/test-requirements.txt index 8d1fa0e5ce..b1789adf9a 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -3,7 +3,6 @@ coverage==4.5.2 pep8==1.7.1 flake8==3.7.7 flake8-copyright==0.2.2 -hacking==1.1.0 astroid==1.6.5 pylint==1.9.4 pylint-plugin-utils>=0.4