easypipinstall
is a dev utility that helps installing Python packages similarly to NPM in NodeJS. It automatically maintains the requirements.txt
, prod-requirements.txt
and setup.cfg
files. It also easily uninstalls all the dependencies from those files. It uses an opinionated pattern where:
- Only two types of dependencies exist:
dev
(via requirements.txt) andprod
(via prod-requirements.txt, which is a subset of requirements.txt). - All dependencies are listed under
requirements.txt
. - By default, dependencies are listed in both
requirements.txt
andprod-requirements.txt
. - Dependencies are not listed under
prod-requirements.txt
when the-D
option (development mode) is used. - The
setup.cfg
file is updated as follows:- By default, the dependency is listed without its version under the
install_requires
property of the[options]
section. - When the
-D
option is used, the dependency is listed without its version under thedev
property of the[options.extras_require]
section.
- By default, the dependency is listed without its version under the
To install:
pip install easypipinstall
This will add three new CLI utilities:
Examples:
easyi numpy
This installs numpy
(via pip install
) then automatically updates the following files:
setup.cfg
(WARNING: this file must already exists):[options] install_requires = numpy
requirements.txt
andprod-requirements.txt
easyi flake8 black -D
This installs flake8
and black
(via pip install
) and then automatically updates the following files:
setup.cfg
(WARNING: this file must already exist):[options.extras_require] dev = black flake8
requirements.txt
only, as those dependencies are installed for development purposes only.
easyu flake8
This uninstalls flake8
as well as all its dependencies. Those dependencies are uninstalled only if other project dependencies do not use them. The setup.cfg
and requirements.txt
are automatically updated.
easyi numpy
This installs numpy
(via pip install
) then automatically updates the following files:
setup.cfg
(WARNING: this file must already exists):[options] install_requires = numpy
requirements.txt
andprod-requirements.txt
easyi flake8 black -D
This installs flake8
and black
(via pip install
) and then automatically updates the following files:
setup.cfg
(WARNING: this file must already exist):[options.extras_require] dev = black flake8
requirements.txt
only, as those dependencies are installed for development purposes only.
easyu flake8
This uninstalls flake8
as well as all its dependencies. Those dependencies are uninstalled only if other project dependencies do not use them. The setup.cfg
and requirements.txt
are automatically updated.
easyv
This returns the current package's version as defined in the setup.cfg
file.
easyv bump
Bumps the patch bit of the version (e.g., before 2.0.0
after 2.0.1
). Up to three updates are applied:
- Updates the version property in the
setup.cfg
file. - If the project is under source control with git and git is installed:
- Updates the
CHANGELOG.md
file using the commit messages between the current branch and the last version tag. If theCHANGELOG.md
file does not exist, it is automatically created. - git commit and tag (using the version number prefixed with
v
) the project.
- Updates the
easyv bump patch
Same as above.
easyv bump minor
Update the minor bit of the version.
easyv bump major
Update the major bit of the version.
easyv bump 2.0.0
Explicitly sets the version to 2.0.0
.
- Clone this project:
git clone https://github.com/nicolasdao/easypipinstall.git
- Browse to the root folder:
cd easypipinstall
- Create a new virtual environment:
python3 -m venv .venv
- Activate this virtual environment:
source .venv/bin/activate
To deactivate that virtual environment:
deactivate
make
commands:
Command | Description |
---|---|
python3 -m venv .venv |
Create a new virtual environment. |
source .venv/bin/activate |
Activate the virtual environment |
deactivate |
Deactivate the virtual environment |
make b |
Builds the package. |
make p |
Publish the package to https://pypi.org. |
make bp |
Builds the package and then publish it to https://pypi.org. |
make bi |
Builds the package and install it locally (pip install -e . ). |
make install |
Install the dependencies defined in the requirements.txt . This file contains all the dependencies (i.e., both prod and dev). |
make install-prod |
Install the dependencies defined in the prod-requirements.txt . This file only contains the production dependencies. |
make n |
Starts a Jupyter notebook for this project. |
make t |
Formats, lints and then unit tests the project. |
make t testpath=<FULLY QUALIFIED TEST PATH> |
Foccuses the unit test on a specific test. For a concrete example, please refer to the Executing a specific test only section. |
make t
This command runs the following three python executables:
black ./
flake8 ./
pytest --capture=no --verbose $(testpath)
black
formats all the.py
files, whileflake8
lints them.black
is configured in thepyproject.toml
file under the[tool.black]
section.flake8
is configured in thesetup.cfg
file under the[flake8]
section.pytest
runs all the.py
files located under thetests
folder. The meaning of each option is as follow:--capture=no
allows theprint
function to send outputs to the terminal.--verbose
displays each test. Without it, the terminal would only display the count of how many passed and failed.$(testpath)
references thetestpath
variable. This variable is set totests
(i.e., thetests
folder) by default. This allows to override this default variable with something else (e.g., a specific test to only run that one).
This project is pre-configured to ignore certain flake8
errors. To add or remove flake8
errors, update the extend-ignore
property under the [flake8]
section in the setup.cfg
file.
In your test file, add the @pytest.mark.skip()
decorator. For example:
import pytest
@pytest.mark.skip()
def test_self_describing_another_test_name():
# ... your test here
One of the output of the make t
command is list of all the test that were run (PASSED and FAILED). For example:
tests/error/test_catch_errors.py::test_catch_errors_basic PASSED
tests/error/test_catch_errors.py::test_catch_errors_wrapped PASSED
tests/error/test_catch_errors.py::test_catch_errors_nested_errors PASSED
tests/error/test_catch_errors.py::test_catch_errors_StackedException_arbitrary_inputs FAILED
To execute a specific test only, add the testpath
option with the test path. For example, to execute the only FAILED test in the example above, run this command:
make t testpath=tests/error/test_catch_errors.py::test_catch_errors_StackedException_arbitrary_inputs
- Make sure the test and lint operations have not produced errors:
make t
- Version and tag this package using one of the following commands (1):
make v cmd=bump
: Use this to bump the patch version.make v cmd=bump ver=minor
: Use this to bump the minor version.make v cmd=bump ver=major
: Use this to bump the major version.make v cmd=bump ver=x.x.x
: Use this to bump the version to a specific value.
- Push those latest changes to your source control repository (incl. tags). For example:
git push origin master --follow-tags
- Build this package:
make b
This command is a wrapper around
python3 -m build
.
- Publish this package to https://pypi.org:
make p
This command is a wrapper around the following commands:
python3 -m build; twine upload dist/*
To test your package locally before deploying it to https://pypi.org, you can run build and install it locally with this command:
make bi
This command buils the package and follows with pip install -e .
.
(1): This step applies three updates:
- Updates the version property in the
setup.cfg
file.- Updates the
CHANGELOG.md
file using the commit messages between the current branch and the last version tag.- git commit and tag (using the version number prefixed with
v
) the project.
BSD 3-Clause License
Copyright (c) 2019-2023, Cloudless Consulting Pty Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.