Skip to content

Commit

Permalink
More Makefile improvements (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffLIrion authored Oct 19, 2023
1 parent 07ab757 commit b3a33b6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 41 deletions.
1 change: 1 addition & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

env:
ENV_GITHUB_ACTIONS: 'ENV_GITHUB_ACTIONS'
Expand Down
97 changes: 61 additions & 36 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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:

Expand All @@ -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

Expand All @@ -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
Expand All @@ -145,54 +170,54 @@ 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

.PHONY: coverage
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


.PHONY: release
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
Expand Down
17 changes: 12 additions & 5 deletions venv_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
aiofiles
async_timeout
# Standard requirements
black
coverage
coveralls
cryptography
flake8
pylint
pytest
sphinx
sphinx-rtd-theme
twine

# Specific requirements for this project
aiofiles
async_timeout
cryptography
libusb1
pyasn1
pycryptodome
pylint
pytest
rsa

0 comments on commit b3a33b6

Please sign in to comment.