From 1bc54d4cb4827b3a411fec880248985e04217b58 Mon Sep 17 00:00:00 2001 From: Jakub Roztocil Date: Wed, 4 Dec 2019 17:49:07 +0100 Subject: [PATCH] Create Python virtual environment (via venv) for tests & development, etc. --- .github/workflows/build.yml | 4 +- .gitignore | 141 ++++++++++++++++++++++++++++++++++-- CONTRIBUTING.rst | 106 +++++++++++++++++++++------ Makefile | 115 +++++++++++++++++++---------- 4 files changed, 298 insertions(+), 68 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7190b4fe..2acc5b7f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,8 +12,8 @@ jobs: - run: pip install --upgrade pip - run: make install - run: make pycodestyle - - run: make test - - run: make codecov + - run: make test-cover + - run: make codecov-upload env: CODECOV_TOKEN: ${{ secrets.CODECOV_REPO_TOKEN }} - run: make test-dist diff --git a/.gitignore b/.gitignore index 7da36e0c..762a8407 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,142 @@ .DS_Store .idea/ -__pycache__/ -dist/ -build/ *.egg-info .cache/ -.tox/ -.coverage *.pyc -*.egg htmlcov + + +############################################################################## +# The bellow is GitHub template for Python project. gitignore. +# +############################################################################## + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ .pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 80d86041..78b1a825 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -29,25 +29,75 @@ is a bigger one, it's always good to discuss before you start working on it. -Creating Development Environment +Development Environment -------------------------------- + +Getting the code +**************** + Go to https://github.com/jakubroztocil/httpie and fork the project repository. .. code-block:: bash - git clone https://github.com//httpie + # Clone your fork + git clone git@github.com:/httpie.git + # Enter the project directory cd httpie + # Create a branch for your changes git checkout -b my_topical_branch - # (Recommended: create a new virtualenv) - # Install dev. requirements and also HTTPie (in editable mode - # so that the `http' command will point to your working copy): - make install +Setup +***** + +The `Makefile`_ contains a bunch of tasks to get you started. Just run +the following command: + + +.. code-block:: bash + + make + +* The commands creates an isolated Python virtual environment inside ``./venv`` + (via the standard library `venv`_ tool); +* installs all dependencies and also installs HTTPie + (in editable mode so that the ``http`` command will point to your + working copy). +* and runs tests (It is the same as running ``make install test``). + + +Python virtual environment +************************** + +Activate the Python virtual environment—created via the ``make install`` +task during `setup`_—for your active shell session using the following command: + +.. code-block:: bash + + source venv/bin/activate + +(If you use ``virtualenvwrapper``, you can also use ``workon httpie`` to +active the environment — we have created a symlink for you. It’s a bit of +a hack but it works™.) + +You should now see ``(httpie)`` next to your shell prompt, and +the ``http`` should point to you development copy: + +.. code-block:: + + (httpie) ~/Code/httpie $ which http + /Users/jakub/Code/httpie/venv/bin/http + (httpie) ~/Code/httpie $ http --version + 2.0.0-dev + +(Btw, you don’t need to activate the virtual environment if you just want +run some of the ``make`` tasks. You can also invoke the development +version of HTTPie directly with ``./venv/bin/http`` without having to activate +the environment first. The same goes for ``./venv/bin/py.test``, etc.). Making Changes @@ -57,36 +107,47 @@ Please make sure your changes conform to `Style Guide for Python Code`_ (PEP8) and that ``make pycodestyle`` passes. -Testing -------- +Testing & CI +------------ -Before opening a pull requests, please make sure the `test suite`_ passes -in all of the `supported Python environments`_. You should also add tests -for any new features and bug fixes. +Please add tests for any new features and bug fixes. -HTTPie uses `pytest`_ and `Tox`_ for testing. +When you open a pull request, +`Github Actions `_ +will automatically run HTTPie’s `test suite`_ against your code +so please make sure all checks pass. -Running all tests: -****************** +Running tests locally +********************* + +HTTPie uses the `pytest`_ runner. It also uses `Tox`_ which allows you to run +tests on multiple Python versions even when testing locally. + .. code-block:: bash - # Run all tests on the current Python interpreter with coverage + # Run tests on the current Python interpreter with coverage. make test + # Run tests with coverage + make test-cover + # Run all tests in all of the supported and available Pythons via Tox make test-tox - # Run all tests for code as well as packaging, etc. - make test-all - # Test PEP8 compliance make pycodestyle + # Run extended tests — for code as well as .rst files syntax, packaging, etc. + make test-all -Running specific tests: -*********************** + +Running specific tests +********************** + +After you have activated your virtual environment (see `setup`_), you +can run specific tests from the terminal: .. code-block:: bash @@ -104,7 +165,9 @@ Running specific tests: ----- See `Makefile`_ for additional development utilities. -Don't forget to add yourself to `AUTHORS`_! + + +Finally, don't forget to add yourself to `AUTHORS`_! .. _Tox: http://tox.testrun.org @@ -112,6 +175,7 @@ Don't forget to add yourself to `AUTHORS`_! .. _existing issues: https://github.com/jakubroztocil/httpie/issues?state=open .. _AUTHORS: https://github.com/jakubroztocil/httpie/blob/master/AUTHORS.rst .. _Makefile: https://github.com/jakubroztocil/httpie/blob/master/Makefile +.. _venv: https://docs.python.org/3/library/venv.html .. _pytest: https://pytest.org/ .. _Style Guide for Python Code: https://python.org/dev/peps/pep-0008/ .. _test suite: https://github.com/jakubroztocil/httpie/tree/master/tests diff --git a/Makefile b/Makefile index 1b6a3007..a141b57f 100644 --- a/Makefile +++ b/Makefile @@ -2,44 +2,88 @@ # See ./CONTRIBUTING.rst ############################################################################### +ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) VERSION=$(shell grep __version__ httpie/__init__.py) -REQUIREMENTS="requirements-dev.txt" -TAG="\n\n\033[0;32m\#\#\# " -END=" \#\#\# \033[0m\n" +REQUIREMENTS=requirements-dev.txt +H1="\n\n\033[0;32m\#\#\# " +H1END=" \#\#\# \033[0m\n" + + +# Only used to create our venv. +SYSTEM_PYTHON=python3 + +VENV_ROOT=venv +VENV_BIN=$(VENV_ROOT)/bin +VENV_PIP=$(VENV_BIN)/pip3 +VENV_PYTHON=$(VENV_BIN)/python3 all: uninstall-httpie install test -install: - @echo $(TAG)Installing dev requirements$(END) - pip install --upgrade -r $(REQUIREMENTS) +install: venv + @echo $(H1)Installing dev requirements$(H1END) + $(VENV_PIP) install --upgrade -r $(REQUIREMENTS) - @echo $(TAG)Installing HTTPie$(END) - pip install --upgrade --editable . + @echo $(H1)Installing HTTPie$(H1END) + $(VENV_PIP) install --upgrade --editable . @echo clean: - @echo $(TAG)Cleaning up$(END) + @echo $(H1)Cleaning up$(H1END) + rm -rf $(VENV_ROOT) + # Symlink for virtualenvwrapper, if we’ve created one. + [ -n "$(WORKON_HOME)" -a -L "$(WORKON_HOME)/httpie" -a -f "$(WORKON_HOME)/httpie" ] && rm $(WORKON_HOME)/httpie || true rm -rf .tox *.egg dist build .coverage .cache .pytest_cache httpie.egg-info - find . -name '__pycache__' -delete -print -o -name '*.pyc' -delete -print + find . -name '__pycache__' -delete -o -name '*.pyc' -delete @echo +venv: + @echo $(H1)Creating a Python environment $(VENV_ROOT) $(H1END) + + $(SYSTEM_PYTHON) -m venv --prompt httpie $(VENV_ROOT) + + @echo + @echo done. + @echo + @echo To active it manually, run: + @echo + @echo " source $(VENV_BIN)/activate" + @echo + @echo '(learn more: https://docs.python.org/3/library/venv.html)' + @echo + @if [ -n "$(WORKON_HOME)" ]; then \ + echo $(ROOT_DIR) > $(VENV_ROOT)/.project; \ + if [ ! -d $(WORKON_HOME)/httpie -a ! -L $(WORKON_HOME)/httpie ]; then \ + ln -s $(ROOT_DIR)/$(VENV_ROOT) $(WORKON_HOME)/httpie ; \ + echo ''; \ + echo 'Since you use virtualenvwrapper, we created a symlink'; \ + echo 'so you can also use "workon httpie" to activate the venv.'; \ + echo ''; \ + fi; \ + fi + + ############################################################################### # Testing ############################################################################### test: - @echo $(TAG)Running tests on the current Python interpreter with coverage $(END) - py.test --cov ./httpie --cov ./tests --doctest-modules --verbose ./httpie ./tests + @echo $(H1)Running tests on the current Python interpreter $(HEADER_EXTRA) $(H1END) + $(VENV_BIN)/py.test $(COV) ./httpie $(COV) ./tests --doctest-modules --verbose ./httpie ./tests @echo +test-cover: COV=--cov +test-cover: HEADER_EXTRA='(with coverage)' +test-cover: test + + # test-all is meant to test everything — even this Makefile -test-all: uninstall-all clean install test test-tox test-dist pycodestyle +test-all: clean install test test-tox test-dist pycodestyle @echo @@ -48,36 +92,38 @@ test-dist: test-sdist test-bdist-wheel test-tox: uninstall-httpie install - @echo $(TAG)Running tests on all Pythons via Tox$(END) + @echo $(H1)Running tests on all Pythons via Tox$(H1END) tox @echo test-sdist: clean uninstall-httpie - @echo $(TAG)Testing sdist build an installation$(END) - python setup.py sdist - pip install --force-reinstall --upgrade dist/*.gz - which http + @echo $(H1)Testing sdist build an installation$(H1END) + $(VENV_PYTHON) setup.py sdist + $(VENV_PIP) install --force-reinstall --upgrade dist/*.gz + $(VENV_BIN)/http --version @echo test-bdist-wheel: clean uninstall-httpie - @echo $(TAG)Testing wheel build an installation$(END) - python setup.py bdist_wheel - pip install --force-reinstall --upgrade dist/*.whl - which http + @echo $(H1)Testing wheel build an installation$(H1END) + $(VENV_PYTHON) setup.py bdist_wheel + $(VENV_PIP) install --force-reinstall --upgrade dist/*.whl + $(VENV_BIN)/http --version @echo pycodestyle: - which pycodestyle || pip install pycodestyle - pycodestyle + @echo $(H1)Running pycodestyle$(H1END) + @[ -f $(VENV_BIN)/pycodestyle ] || $(VENV_PIP) install pycodestyle + $(VENV_BIN)/pycodestyle httpie/ tests/ extras/ *.py @echo -codecov: - which codecov || pip install codecov - codecov --required +codecov-upload: + @echo $(H1)Running codecov$(H1END) + @[ -f $(VENV_BIN)/codecov ] || $(VENV_PIP) install codecov + $(VENV_BIN)/codecov --required @echo @@ -90,7 +136,7 @@ publish: test-all publish-no-test publish-no-test: - @echo $(TAG)Testing wheel build an installation$(END) + @echo $(H1)Testing wheel build an installation$(H1END) @echo "$(VERSION)" @echo "$(VERSION)" | grep -q "dev" && echo '!!!Not publishing dev version!!!' && exit 1 || echo ok python setup.py sdist bdist_wheel @@ -104,8 +150,8 @@ publish-no-test: ############################################################################### uninstall-httpie: - @echo $(TAG)Uninstalling httpie$(END) - - pip uninstall --yes httpie &2>/dev/null + @echo $(H1)Uninstalling httpie$(H1END) + - $(VENV_PIP) uninstall --yes httpie &2>/dev/null @echo "Verifying…" cd .. && ! python -m httpie --version &2>/dev/null @@ -114,15 +160,6 @@ uninstall-httpie: @echo -uninstall-all: uninstall-httpie - - @echo $(TAG)Uninstalling httpie requirements$(END) - - pip uninstall --yes pygments requests - - @echo $(TAG)Uninstalling development requirements$(END) - - pip uninstall --yes -r $(REQUIREMENTS) - - ############################################################################### # Docs ###############################################################################