diff --git a/Makefile b/Makefile index d18a86e..9c34732 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,19 @@ LINT_TEST_DIR := false export PATH := $(abspath venv)/bin:${PATH} +# Binaries to run +BLACK := $(abspath venv)/bin/black +COVERAGE := $(abspath venv)/bin/coverage +FLAKE8 := $(abspath venv)/bin/flake8 +PIP := $(abspath venv)/bin/pip3 +PYLINT := $(abspath venv)/bin/pylint +PYTEST := $(abspath venv)/bin/pytest +PYTHON := $(abspath venv)/bin/python +SPHINX_APIDOC := $(abspath venv)/bin/sphinx-apidoc +TWINE := $(abspath venv)/bin/twine + # Whether to include "*_async.py" files -INCLUDE_ASYNC = $(shell python --version | grep -q "Python 3.[7891]" && echo "true" || echo "false") +INCLUDE_ASYNC = $(shell $(PYTHON) --version | grep -q "Python 3.[7891]" && echo "true" || echo "false") # Async vs. Sync files PACKAGE_ASYNC_FILES = $(shell ls -m $(PACKAGE_DIR)/*_async.py 2>/dev/null) @@ -24,6 +35,7 @@ TEST_SYNC_FILES = $(shell cd $(TEST_DIR) && ls test*.py | grep -v async) VENV_REQUIREMENTS_TXT := $(wildcard venv_requirements.txt) SETUP_PY := $(wildcard setup.py) + # A prerequisite for forcing targets to run FORCE: @@ -49,25 +61,38 @@ venv: venv/.bin venv/.requirements venv/.setup .git/hooks/pre-commit ## Create venv/.bin: ## Create the virtual environment if [ -z "$$ENV_GITHUB_ACTIONS" ]; then \ - echo -e "If this target fails, you can perform this action manually via:\n\n make clean-venv && python3 -m venv venv && source venv/bin/activate && pip install -U setuptools && echo -e '*.*\n**/' > venv/.gitignore && touch venv/.bin\n\n"; \ - apt list -a --installed python3-venv 2>&1 | grep -q installed || (sudo apt update && sudo apt install python3-venv); \ + echo -e "If this target fails, you can perform this action manually via:\n\n make clean-venv && python3 -m venv venv && source venv/bin/activate && pip install -U setuptools && echo -e '*.*\\\n**/' > venv/.gitignore && touch venv/.bin\n\n"; \ + apt list -a --installed python3-venv 2>&1 | grep -q installed || sudo apt update && sudo apt install python3-venv; \ python3 -m venv venv; \ - pip install -U setuptools; \ + $(PIP) install -U setuptools; \ + else \ + mkdir -p venv/bin; \ + ln -s $$(which pip) $(PIP); \ + ln -s $$(which python) $(PYTHON); \ fi - mkdir -p venv + mkdir -p venv/bin echo '*.*\n**/' > venv/.gitignore touch venv/.bin venv/.requirements: venv/.bin $(VENV_REQUIREMENTS_TXT) ## Install the requirements from 'venv_requirements.txt' in the virtual environment ifneq ("$(wildcard venv_requirements.txt)", "") - pip install -U -r venv_requirements.txt + $(PIP) install -U -r venv_requirements.txt + if ! [ -z "$$ENV_GITHUB_ACTIONS" ]; then \ + ln -s $$(which black) $(BLACK); \ + ln -s $$(which coverage) $(COVERAGE); \ + ln -s $$(which flake8) $(FLAKE8); \ + ln -s $$(which pylint) $(PYLINT); \ + ln -s $$(which pytest) $(PYTEST); \ + ln -s $$(which sphinx-apidoc) $(SPHINX_APIDOC); \ + ln -s $$(which twine) $(TWINE); \ + fi endif touch venv/.requirements # Install the package in the virtual environment venv/.setup: venv/.bin $(SETUP_PY) ifneq ("$(wildcard setup.py)", "") - pip install . + $(PIP) install . endif touch venv/.setup @@ -88,52 +113,52 @@ pre-commit: .git/hooks/pre-commit ## Create the pre-commit hook # Linting and code analysis .PHONY: black black: venv ## Format the code using black - black --safe --line-length 120 --target-version py35 $(PACKAGE_DIR) - black --safe --line-length 120 --target-version py35 $(TEST_DIR) + $(BLACK) --safe --line-length 120 --target-version py35 $(PACKAGE_DIR) + $(BLACK) --safe --line-length 120 --target-version py35 $(TEST_DIR) ifneq ("$(wildcard setup.py)", "") - black --safe --line-length 120 --target-version py35 setup.py + $(BLACK) --safe --line-length 120 --target-version py35 setup.py endif .PHONY: lint-black lint-black: venv ## Check that the code is formatted using black - black --check --line-length 120 --safe --target-version py35 $(PACKAGE_DIR) - black --check --line-length 120 --safe --target-version py35 $(TEST_DIR) + $(BLACK) --check --line-length 120 --safe --target-version py35 $(PACKAGE_DIR) + $(BLACK) --check --line-length 120 --safe --target-version py35 $(TEST_DIR) ifneq ("$(wildcard setup.py)", "") - black --check --line-length 120 --safe --target-version py35 setup.py + $(BLACK) --check --line-length 120 --safe --target-version py35 setup.py endif .PHONY: lint-flake8 lint-flake8: venv ## Check the code using flake8 ifeq ($(INCLUDE_ASYNC), true) - flake8 $(PACKAGE_DIR) + $(FLAKE8) $(PACKAGE_DIR) ifeq ($(LINT_TEST_DIR), true) - flake8 $(TEST_DIR) + $(FLAKE8) $(TEST_DIR) endif else - flake8 $(PACKAGE_DIR) --exclude="$(PACKAGE_ASYNC_FILES)" + $(FLAKE8) $(PACKAGE_DIR) --exclude="$(PACKAGE_ASYNC_FILES)" ifeq ($(LINT_TEST_DIR), true) - flake8 $(TEST_DIR) --exclude="$(TEST_ASYNC_FILES)" + $(FLAKE8) $(TEST_DIR) --exclude="$(TEST_ASYNC_FILES)" endif endif ifneq ("$(wildcard setup.py)", "") - flake8 setup.py + $(FLAKE8) setup.py endif .PHONY: lint-pylint lint-pylint: venv ## Check the code using pylint ifeq ($(INCLUDE_ASYNC), true) - pylint $(PACKAGE_DIR) + $(PYLINT) $(PACKAGE_DIR) ifeq ($(LINT_TEST_DIR), true) - pylint $(TEST_DIR) + $(PYLINT) $(TEST_DIR) endif else - pylint $(PACKAGE_DIR) --ignore="$(PACKAGE_ASYNC_FILES)" + $(PYLINT) $(PACKAGE_DIR) --ignore="$(PACKAGE_ASYNC_FILES)" ifeq ($(LINT_TEST_DIR), true) - pylint $(TEST_DIR) --ignore="$(TEST_ASYNC_FILES)" + $(PYLINT) $(TEST_DIR) --ignore="$(TEST_ASYNC_FILES)" endif endif ifneq ("$(wildcard setup.py)", "") - pylint setup.py + $(PYLINT) setup.py endif .PHONY: lint @@ -145,15 +170,15 @@ lint: lint-black lint-flake8 lint-pylint ## Run all linting checks on the code test: venv ## Run the unit tests ifeq ($(INCLUDE_ASYNC), true) ifeq ($(USE_PYTEST), true) - pytest $(TEST_DIR) + $(PYTEST) $(TEST_DIR) else - python -m unittest discover -s $(TEST_DIR)/ -t . + $(PYTHON) -m unittest discover -s $(TEST_DIR)/ -t . endif else ifeq ($(USE_PYTEST), true) - pytest $(TEST_DIR) --ignore-glob="*async.py" + $(PYTEST) $(TEST_DIR) --ignore-glob="*async.py" else - for synctest in $(TEST_SYNC_FILES); do echo "\033[1;32m$(TEST_DIR)/$$synctest\033[0m" && python -m unittest "$(TEST_DIR)/$$synctest"; done + for synctest in $(TEST_SYNC_FILES); do echo "\033[1;32m$(TEST_DIR)/$$synctest\033[0m" && $(PYTHON) -m unittest "$(TEST_DIR)/$$synctest"; done endif endif @@ -161,29 +186,29 @@ endif coverage: venv ## Run the unit tests and produce coverage info ifeq ($(INCLUDE_ASYNC), true) ifeq ($(USE_PYTEST), true) - coverage run --source $(PACKAGE_DIR) -m pytest $(TEST_DIR)/ && coverage report -m + $(COVERAGE) run --source $(PACKAGE_DIR) -m pytest $(TEST_DIR)/ && $(COVERAGE) report -m else - coverage run --source $(PACKAGE_DIR) -m unittest discover -s $(TEST_DIR) -t . && coverage report -m + $(COVERAGE) run --source $(PACKAGE_DIR) -m unittest discover -s $(TEST_DIR) -t . && $(COVERAGE) report -m endif else ifeq ($(USE_PYTEST), true) - coverage run --source $(PACKAGE_DIR) -m pytest $(TEST_DIR)/ --ignore-glob="*async.py" && coverage report -m + $(COVERAGE) run --source $(PACKAGE_DIR) -m pytest $(TEST_DIR)/ --ignore-glob="*async.py" && $(COVERAGE) report -m else - for synctest in $(TEST_SYNC_FILES); do echo "\033[1;32m$(TEST_DIR)/$$synctest\033[0m" && coverage run --source $(PACKAGE_DIR) -m unittest "$(TEST_DIR)/$$synctest"; done - coverage report -m + for synctest in $(TEST_SYNC_FILES); do echo "\033[1;32m$(TEST_DIR)/$$synctest\033[0m" && $(COVERAGE) run --source $(PACKAGE_DIR) -m unittest "$(TEST_DIR)/$$synctest"; done + $(COVERAGE) report -m endif endif .PHONY: htmlcov htmlcov: coverage ## Produce a coverage report - coverage html + $(COVERAGE) html # Documentation .PHONY: docs docs: venv ## Build the documentation rm -rf $(DOCS_DIR)/build - @cd $(DOCS_DIR) && sphinx-apidoc -f -e -o source/ $(CURDIR)/$(PACKAGE_DIR)/ + @cd $(DOCS_DIR) && $(SPHINX_APIDOC) -f -e -o source/ $(CURDIR)/$(PACKAGE_DIR)/ @cd $(DOCS_DIR) && make html && make html @@ -191,8 +216,8 @@ docs: venv ## Build the documentation release: ## Make a release and upload it to pypi rm -rf dist scripts/git_tag.sh - python setup.py sdist bdist_wheel - twine upload dist/* + $(PYTHON) setup.py sdist bdist_wheel + $(TWINE) upload dist/* .PHONY: all diff --git a/venv_requirements.txt b/venv_requirements.txt index 836a04b..a11d971 100644 --- a/venv_requirements.txt +++ b/venv_requirements.txt @@ -1,12 +1,14 @@ -adb-shell[async,usb] -aiofiles +# Standard requirements black coverage coveralls flake8 pylint pytest -pyyaml sphinx sphinx-rtd-theme -tk +twine + +# Specific requirements for this project +adb-shell[async,usb] +aiofiles