# Copyright (C) 2003-2022, Stefan Schwarzer <sschwarzer@sschwarzer.net>
# and ftputil contributors (see `doc/contributors.txt`)
# See the file LICENSE for licensing terms.
# This Makefile requires GNU Make.
SHELL=/bin/sh
PROJECT_DIR=$(shell pwd)
VERSION=$(shell cat VERSION)
PYTHON_BINARY?=python3
PYTEST=${PYTHON_BINARY} -m pytest
TEST_DIR=${PROJECT_DIR}/test
SOURCE_DIR=${PROJECT_DIR}/ftputil
WEBSITE_DIR=${PROJECT_DIR}/website
SED=sed -i'' -r -e
PYTHONPATH=${PROJECT_DIR}:${TEST_DIR}
# Name test files. Make sure the long-running tests come last.
TEST_FILES=$(shell ls -1 ${TEST_DIR}/test_*.py | \
grep -v "test_real_ftp.py" | \
grep -v "test_public_servers.py" ) \
${TEST_DIR}/test_real_ftp.py \
${TEST_DIR}/test_public_servers.py
# Put this first to avoid accidental patching if running `make`
# without target.
.PHONY: dummy
dummy:
# Patch various files to refer to a new version.
.PHONY: patch
patch:
@echo "Patching files"
${SED} "s/^__version__ = \".*\"/__version__ = \"${VERSION}\"/" \
${SOURCE_DIR}/version.py
# Use `1,15` as range. This is a compromise in that we don't want to patch
# too much in the remaining document, but we still want to be a bit
# flexible if the patched lines move a bit.
${SED} "1,15s/^\*\*Version:\*\* .*\\\\/**Version:** ${VERSION}\\\\/" \
${WEBSITE_DIR}/documentation.md
${SED} "1,15s/^\*\*Date:\*\* .*\\\\/**Date:** `date +"%Y-%m-%d"`\\\\/" \
${WEBSITE_DIR}/documentation.md
${SED} "s/^Version: .*/Version: ${VERSION}/" PKG-INFO
${SED} "s/(\/wiki\/Download\/ftputil-).*(\.tar\.gz)/\1${VERSION}\2/" \
PKG-INFO
# Website maintenance
.PHONY: serve_website
serve_website:
(cd website && bundler exec jekyll serve)
.PHONY: website
website:
(cd website && bundler exec jekyll build)
.PHONY: upload_website
upload_website: website
hetzner-sync website/_site ftputil
# Quality assurance
.PHONY: test
test:
@echo -e "=== Running fast tests for ftputil ${VERSION} ===\n"
${PYTEST} -m "not slow_test" test
# Alternative for symmetry with target `all_tests`
.PHONY: tests
tests: test
all_tests:
@echo -e "=== Running all tests for ftputil ${VERSION} ===\n"
${PYTEST} test
.PHONY: tox_test
tox_test:
# Gets settings from `tox.ini`
tox
.PHONY: coverage
coverage:
py.test --cov ftputil --cov-report html test
.PHONY: pylint
pylint:
pylint --rcfile=pylintrc ${PYLINT_OPTS} ${SOURCE_DIR}/*.py | \
less --quit-if-one-screen
# Make a distribution tarball.
.PHONY: dist
dist: clean patch pylint
# Delete contents of `.tox`, but keep the directory.
rm -rf .tox/*
${PYTHON_BINARY} setup.py sdist
# `MANIFEST` is auto-generated by distutils from `MANIFEST.in`.
rm MANIFEST
.PHONY: extdist
extdist: all_tests dist upload
# Upload package to PyPI.
# See also https://packaging.python.org/tutorials/packaging-projects/
.PHONY: upload
upload:
@echo "Uploading new version to PyPI"
${PYTHON_BINARY} -m twine upload dist/ftputil-${VERSION}.tar.gz
# Remove files with `orig` suffix (caused by `hg revert`).
.PHONY: cleanorig
cleanorig:
find ${PROJECT_DIR} -name '*.orig' -exec rm {} \;
# Remove generated files (but no distribution packages).
.PHONY: clean
clean:
rm -f ${DOC_TARGETS}
# Use absolute path to ensure we delete the right directory.
rm -rf ${PROJECT_DIR}/build
find ${PROJECT_DIR} -type f -name "*.pyc" -exec rm {} \;
find ${PROJECT_DIR} -type d -name "__pycache__" -exec rm -r {} \;
find ${PROJECT_DIR}/.tox -type d -name "__pycache__" -exec rm -r {} \;
# Help testing test installations. Note that `pip uninstall`
# doesn't work if the package wasn't installed with pip.
.PHONY: remove_from_env
remove_from_env:
rm -rf ${VIRTUAL_ENV}/doc/ftputil
rm -rf ${VIRTUAL_ENV}/lib/python3.*/site-packages/ftputil
# For integration tests in `test_real_ftp.py`
DOCKER?=docker
IMAGE?=localhost/sschwarzer/ftputil-test-server:0.3
CONTAINER?=test_server_container
.PHONY: build_test_server_image
build_test_server_image:
${DOCKER} image build -t ${IMAGE} test_server
#${DOCKER} image rm $(shell ${DOCKER} image ls -q --filter="dangling=true")
.PHONY: run_test_server
run_test_server: build_test_server_image
# If container exists, remove it.
if [ ! -z "$(shell ${DOCKER} container ls -q -a --filter name=${CONTAINER})" ]; then \
${DOCKER} container rm -f ${CONTAINER}; \
fi
${DOCKER} container run --rm --detach --privileged --name ${CONTAINER} \
-p 127.0.0.1:2121:2121 -p 127.0.0.1:30000-30009:30000-30009 ${IMAGE}