Skip to content

Commit

Permalink
Merge 8b503ee into 94a3f01
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffLIrion committed Oct 18, 2023
2 parents 94a3f01 + 8b503ee commit 84061b8
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 55 deletions.
22 changes: 8 additions & 14 deletions .github/workflows/python-package.yml
Expand Up @@ -9,6 +9,9 @@ on:
pull_request:
branches: [ master ]

env:
ENV_GITHUB_ACTIONS: 'ENV_GITHUB_ACTIONS'

jobs:
build:

Expand All @@ -26,22 +29,13 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pylint coveralls
if python --version 2>&1 | grep -q "Python 2"; then pip install mock rsa==4.0; fi
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
pip install .
if python --version 2>&1 | grep -q "Python 3.7" || python --version 2>&1 | grep -q "Python 3.8" || python --version 2>&1 | grep -q "Python 3.9" || python --version 2>&1 | grep -q "Python 3.10"; then pip install aiofiles async_timeout adb-shell[usb]; fi
- name: Check formatting with black
run: |
if python --version 2>&1 | grep -q "Python 3.7" || python --version 2>&1 | grep -q "Python 3.8" || python --version 2>&1 | grep -q "Python 3.9" || python --version 2>&1 | grep -q "Python 3.10"; then pip install black && make lint-black; fi
- name: Lint with pylint and flake8
make venv
- name: Linting checks with pylint, flake8, and black
run: |
if python --version 2>&1 | grep -q "Python 2" || python --version 2>&1 | grep -q "Python 3.5" || python --version 2>&1 | grep -q "Python 3.6"; then flake8 androidtv/ --exclude="androidtv/setup_async.py,androidtv/basetv/basetv_async.py,androidtv/androidtv/androidtv_async.py,androidtv/firetv/firetv_async.py,androidtv/adb_manager/adb_manager_async.py" && pylint --ignore="setup_async.py,basetv_async.py,androidtv_async.py,firetv_async.py,adb_manager_async.py" androidtv/; fi
if python --version 2>&1 | grep -q "Python 3.7" || python --version 2>&1 | grep -q "Python 3.8" || python --version 2>&1 | grep -q "Python 3.9" || python --version 2>&1 | grep -q "Python 3.10"; then flake8 androidtv/ && pylint androidtv/; fi
- name: Test with unittest
make lint
- name: Test with pytest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_SERVICE_NAME: github
run: |
if python --version 2>&1 | grep -q "Python 2" || python --version 2>&1 | grep -q "Python 3.5" || python --version 2>&1 | grep -q "Python 3.6" ; then for synctest in $(cd tests && ls test*.py | grep -v async); do python -m unittest discover -s tests/ -t . -p "$synctest" || exit 1; done; fi
if python --version 2>&1 | grep -q "Python 3.7" || python --version 2>&1 | grep -q "Python 3.8" || python --version 2>&1 | grep -q "Python 3.9"|| python --version 2>&1 | grep -q "Python 3.10"; then coverage run --source androidtv -m unittest discover -s tests/ -t . && coverage report -m --fail-under 100 && coveralls; fi
make coverage && coveralls
225 changes: 188 additions & 37 deletions Makefile
@@ -1,48 +1,199 @@
.PHONY: release
release:
rm -rf dist
rm -rf build
scripts/git_tag.sh
python setup.py sdist bdist_wheel
twine upload dist/*
#-------------------- ONLY MODIFY CODE IN THIS SECTION --------------------#
PACKAGE_DIR := androidtv
TEST_DIR := tests
DOCS_DIR := docs

.PHONY: docs
docs:
@cd docs/source && rm -f androidtv*.rst
@cd docs && sphinx-apidoc -f -e -o source/ ../androidtv/
@cd docs && make html && make html
# Change to false if you don't want to use pytest
USE_PYTEST := true

SYNCTESTS := $(shell cd tests && ls test*.py | grep -v async)
# Change this to false if you don't want to run linting checks on the tests
LINT_TEST_DIR := false
#-------------------- DO NOT MODIFY CODE BELOW!!!!!!!! --------------------#

.PHONY: test
test:
python --version 2>&1 | grep -q "Python 2" && (for synctest in $(SYNCTESTS); do python -m unittest discover -s tests/ -t . -p "$$synctest"; done) || true
python --version 2>&1 | grep -q "Python 3" && python -m unittest discover -s tests/ -t . || true
export PATH := $(abspath venv)/bin:${PATH}

.PHONY: coverage
coverage:
coverage run --source androidtv -m unittest discover -s tests/ -t . && coverage html && coverage report -m
# Whether to include "*_async.py" files
INCLUDE_ASYNC = $(shell python --version | grep -q "Python 3.[7891]" && echo "true" || echo "false")

.PHONY: tdd
tdd:
coverage run --source androidtv -m unittest discover -s tests/ -t . && coverage report -m
# Async vs. Sync files
PACKAGE_ASYNC_FILES = $(shell ls -m $(PACKAGE_DIR)/*_async.py 2>/dev/null)
TEST_ASYNC_FILES = $(shell ls -m $(TEST_DIR)/*_async.py 2>/dev/null)
TEST_SYNC_FILES = $(shell cd $(TEST_DIR) && ls test*.py | grep -v async)

.PHONY: lint
lint:
flake8 androidtv/ && pylint androidtv/
# Target prerequisites that may or may not exist
VENV_REQUIREMENTS_TXT := $(wildcard venv_requirements.txt)
SETUP_PY := $(wildcard setup.py)

# A prerequisite for forcing targets to run
FORCE:

# Help!
help: ## Show this help menu
@echo "\n\033[1mUsage:\033[0m"; \
awk -F ':|##' '/^[^\t].+?:.*?##/ { printf "\033[36m make %-20s\033[0m %s\n", $$1, $$NF }' $(MAKEFILE_LIST) | grep -v "make venv/\." | sort
@echo ""
@echo "NOTES:"
@echo "- The 'venv/.bin' target may fail because newer Python versions include the 'venv' package. Follow the instructions to create the virtual environment manually."
ifneq ("$(wildcard scripts/pre-commit.sh)", "")
@echo "- To install the git pre-commit hook:\n\n scripts/pre-commit.sh\n"
endif
@echo "- You may need to activate the virtual environment prior to running any Make commands:\n\n source venv/bin/activate\n"


# Virtual environment targets
.PHONY: clean-venv
clean-venv: ## Remove the virtual environment
rm -rf venv

venv: venv/.bin venv/.requirements venv/.setup .git/hooks/pre-commit ## Create the virtual environment and install all necessary packages

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); \
python3 -m venv venv; \
pip install -U setuptools; \
fi
mkdir -p venv
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
endif
touch venv/.requirements

# Install the package in the virtual environment
venv/.setup: venv/.bin $(SETUP_PY)
ifneq ("$(wildcard setup.py)", "")
pip install .
endif
touch venv/.setup

.PHONY: uninstall
uninstall:
rm -f venv/.setup

.PHONY: install
install: uninstall venv/.setup ## Install the package in the virtual environment

# Create the pre-commit hook
.git/hooks/pre-commit:
./scripts/pre-commit.sh MAKE_PRECOMMIT_HOOK

.PHONY: pre-commit
pre-commit: .git/hooks/pre-commit ## Create the pre-commit hook

# Linting and code analysis
.PHONY: black
black:
black --safe --line-length 120 --target-version py35 androidtv
black --safe --line-length 120 --target-version py35 tests
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)
ifneq ("$(wildcard setup.py)", "")
black --safe --line-length 120 --target-version py35 setup.py
endif

.PHONY: lint-black
lint-black:
black --check --safe --line-length 120 --target-version py35 androidtv
black --check --safe --line-length 120 --target-version py35 tests
black --check --safe --line-length 120 --target-version py35 setup.py

.PHONY: alltests
alltests:
flake8 androidtv/ && pylint androidtv/ && coverage run --source androidtv -m unittest discover -s tests/ -t . && coverage report -m
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)
ifneq ("$(wildcard 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)
ifeq ($(LINT_TEST_DIR), true)
flake8 $(TEST_DIR)
endif
else
flake8 $(PACKAGE_DIR) --exclude="$(PACKAGE_ASYNC_FILES)"
ifeq ($(LINT_TEST_DIR), true)
flake8 $(TEST_DIR) --exclude="$(TEST_ASYNC_FILES)"
endif
endif
ifneq ("$(wildcard setup.py)", "")
flake8 setup.py
endif

.PHONY: lint-pylint
lint-pylint: venv ## Check the code using pylint
ifeq ($(INCLUDE_ASYNC), true)
pylint $(PACKAGE_DIR)
ifeq ($(LINT_TEST_DIR), true)
pylint $(TEST_DIR)
endif
else
pylint $(PACKAGE_DIR) --ignore="$(PACKAGE_ASYNC_FILES)"
ifeq ($(LINT_TEST_DIR), true)
pylint $(TEST_DIR) --ignore="$(TEST_ASYNC_FILES)"
endif
endif
ifneq ("$(wildcard setup.py)", "")
pylint setup.py
endif

.PHONY: lint
lint: lint-black lint-flake8 lint-pylint ## Run all linting checks on the code


# Testing and coverage.
.PHONY: test
test: venv ## Run the unit tests
ifeq ($(INCLUDE_ASYNC), true)
ifeq ($(USE_PYTEST), true)
pytest $(TEST_DIR)
else
python -m unittest discover -s $(TEST_DIR)/ -t .
endif
else
ifeq ($(USE_PYTEST), true)
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
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
else
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
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
endif
endif

.PHONY: htmlcov
htmlcov: coverage ## Produce a coverage report
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) && 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/*


.PHONY: all
all: lint htmlcov ## Run all linting checks and unit tests and produce a coverage report
71 changes: 71 additions & 0 deletions scripts/pre-commit.sh
@@ -0,0 +1,71 @@
#!/bin/bash

set -e

function make_pre_commit() {
# setup pre-commit hook
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
echo -e "#!/bin/bash\n\n./scripts/pre-commit.sh 'placeholder_argument'" > "$DIR/../.git/hooks/pre-commit"
chmod a+x "$DIR/../.git/hooks/pre-commit"
echo "pre-commit hook successfully configured"
}

# if no arguments are passed, create the pre-commit hook
if [ "$#" -eq 0 ]; then
read -p "Do you want to setup the git pre-commit hook? [Y/n] " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
make_pre_commit
else
echo "pre-commit hook not configured"
fi
exit 0
fi

# if the argument passed is "MAKE_PRECOMMIT_HOOK", then make the pre-commit hook
if [[ $1 == "MAKE_PRECOMMIT_HOOK" ]]; then
make_pre_commit
exit 0
fi

# THE PRE-COMMIT HOOK

# get the directory of this script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

(
cd "$DIR/.."

no_unstaged_changes=true
echo -e "\n\033[1m1. Checking for unstaged changes...\033[0m"
for staged_file in $(git diff --name-only --cached); do
git diff --name-only | grep -q "${staged_file}" && echo "You have unstaged changes in '${staged_file}'" && no_unstaged_changes=false || true
done

# modified .py files
pyfiles=$(git diff --cached --name-only -- '*.py')

# flake8
flake8_pass=true
if [ "$pyfiles" != "" ]; then
echo -e "\n\033[1m2. Running flake8...\033[0m"
venv/bin/flake8 $pyfiles || flake8_pass=false
else
echo -e "\n\033[1m2. Skipping flake8.\033[0m"
fi

# pylint
pylint_pass=true
if [ "$pyfiles" != "" ]; then
echo -e "\n\033[1m3. Running pylint...\033[0m"
venv/bin/pylint $pyfiles || pylint_pass=false
else
echo -e "\n\033[1m3. Skipping pylint.\033[0m\n"
fi

if [ "$flake8_pass" != "true" ] || [ "$pylint_pass" != "true" ] || [ "$no_unstaged_changes" != "true" ]; then
echo -e "\033[1m\033[31mSome checks failed.\033[0m\n\n NOT RECOMMENDED: If you want to skip the pre-commit hook, use the --no-verify flag.\n"
exit 1
fi
echo -e "\033[1m\033[32mAll checks passed.\033[0m\n"
)
2 changes: 2 additions & 0 deletions setup.py
@@ -1,3 +1,5 @@
"""setup.py file for the androidtv package."""

from setuptools import setup

with open("README.rst") as f:
Expand Down

0 comments on commit 84061b8

Please sign in to comment.