1. Common Package Dependencies
------------------------------
- 1. Python(>= 2.7.5 or >= 3.3)
- 2. nose(http://nose.readthedocs.io/en/latest/)
- 3. nose2(Installation guide http://nose2.readthedocs.io/)
- 4. pep8(https://pypi.python.org/pypi/setuptools-pep8)
- 5. flake8(https://pypi.python.org/pypi/flake8)
- 6. pylint(https://www.pylint.org/)
- 7. Epydoc(http://epydoc.sourceforge.net/)
- 8. nvme-cli(https://github.com/linux-nvme/nvme-cli.git)
+ 1. Python(>= 3.3)
+ 2. nose2 (Installation guide http://nose2.readthedocs.io/)
+ 3. flake8 (https://pypi.python.org/pypi/flake8)
+ 4. mypy (https://pypi.org/project/mypy/)
+ 5. autopep8 (https://pypi.org/project/autopep8/)
+ 6. isort (https://pypi.org/project/isort/)
Python package management system pip can be used to install most of the
listed packages(https://pip.pypa.io/en/stable/installing/) :-
- $ pip install nose nose2 pep8 flake8 pylint epydoc
+ $ pip install nose2 flake8 mypy autopep8 isort
2. Overview
-----------
6. Before writing a new function have a look into TestNVMe to see if it
can be reused.
7. Once testcase is ready make sure :-
- a. Run pep8, flake8, pylint on the testcase and fix errors/warnings.
- -Example "$ make static_check" will run pep8, flake8 and pylint on
- all the python files in current directory.
- b. Execute make doc to generate the documentation.
- -Example "$ make doc" will create and update existing
- documentation.
+ a. Run flake8, mypy, autopep8 and isort on the testcase and fix
+ errors/warnings.
+ - Example "$ ninja -C .build lint-python" will run flake8 and
+ mypy on all the python files in current directory.
+ - Example "$ ninja -C .build fomrat-python" will run autopep8 and
+ isort on all the python files in the current directory.
4. Running testcases with framework
-----------------------------------
$ nose2 --verbose nvme_writezeros_test
$ nose2 --verbose nvme_read_write_test
- 2. Running all the testcases with Makefile :-
- $ make run
+ 2. Running all the testcases with ninja :-
+ $ ninja test -C .build
timeout: 500)
endforeach
endif
+
+python_module = import('python')
+
+python = python_module.find_installation('python3')
+
+mypy = find_program(
+ 'mypy',
+ required : false,
+)
+flake8 = find_program(
+ 'flake8',
+ required : false,
+)
+linter_script = files('run_py_linters.py')
+
+if mypy.found() and flake8.found()
+ run_target(
+ 'lint-python',
+ command : [python, linter_script, 'lint'],
+ )
+else
+ message('Mypy or Flake8 not found. Python linting disabled')
+endif
+
+
+autopep8 = find_program(
+ 'autopep8',
+ required : false,
+)
+isort = find_program(
+ 'isort',
+ required : false,
+)
+
+if autopep8.found() and isort.found()
+ run_target(
+ 'format-python',
+ command : [python, linter_script, 'format'],
+ )
+else
+ message('autopep8 or isort not found. Python formating disabled')
+endif
--- /dev/null
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+# Copied from https://github.com/python-sdbus/python-sdbus
+# Copyright (C) 2020, 2021 igo95862
+
+# This file is part of nvme-cli
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+from __future__ import annotations
+
+from argparse import ArgumentParser
+from os import environ
+from pathlib import Path
+from subprocess import run
+from typing import List
+
+source_root = Path(environ['MESON_SOURCE_ROOT'])
+build_dir = Path(environ['MESON_BUILD_ROOT'])
+
+tests_dir = source_root / 'tests'
+
+all_python_modules = [
+ tests_dir,
+]
+
+mypy_cache_dir = build_dir / '.mypy_cache'
+
+
+def run_mypy(path: Path) -> None:
+ print(f"Running mypy on {path}")
+ run(
+ args=(
+ 'mypy', '--strict',
+ '--cache-dir', mypy_cache_dir,
+ '--python-version', '3.8',
+ '--namespace-packages',
+ '--ignore-missing-imports',
+ path,
+ ),
+ check=False,
+ env={'MYPYPATH': str(tests_dir.absolute()), **environ},
+ )
+
+
+def linter_main() -> None:
+ run(
+ args=(
+ 'flake8',
+ *all_python_modules,
+ ),
+ check=False,
+ )
+
+ for x in all_python_modules:
+ run_mypy(x)
+
+
+def get_all_python_files() -> List[Path]:
+ python_files: List[Path] = []
+
+ for python_module in all_python_modules:
+ if python_module.is_dir():
+ for a_file in python_module.iterdir():
+ if a_file.suffix == '.py':
+ python_files.append(a_file)
+ else:
+ python_files.append(python_module)
+
+ return python_files
+
+
+def formater_main() -> None:
+ all_python_files = get_all_python_files()
+
+ run(
+ args=('autopep8', '--in-place', *all_python_files),
+ check=False,
+ )
+
+ run(
+ args=(
+ 'isort',
+ '-m', 'VERTICAL_HANGING_INDENT',
+ '--trailing-comma',
+ *all_python_files,
+ ),
+ check=False,
+ )
+
+
+def main() -> None:
+ parser = ArgumentParser()
+ parser.add_argument(
+ 'mode',
+ choices=('lint', 'format'),
+ )
+
+ args = parser.parse_args()
+
+ mode = args.mode
+
+ if mode == 'lint':
+ linter_main()
+ elif mode == 'format':
+ formater_main()
+ else:
+ raise ValueError('Unknown mode', mode)
+
+
+if __name__ == '__main__':
+ main()