Reputation: 2874
Background Story I have a python project which uses setuptools for building the source distribution. Pylint is integrated for running tests. And I come from a heavy NodeJs background.
Problem After doing changes to the code, I have several steps which should be run before distributing the application.
And some other requirements like,
pip install -r requirements.txt
In NodeJs projects, I can write a set of shell commands with pre and post subscripts in the package.json file which does the job in a real nice way.
Currently for the python project, I am using a shell script which executes the required steps in required order. One other option I thought of was having a package.json just for the sake of handling the dev environment. But it doesn't sound pythonic!
How can I automate these steps in an elegant pythonic way?
Upvotes: 2
Views: 684
Reputation: 66171
After doing changes to the code, I have several steps which should be run before distributing the application.
You can chain multiple actions by passing multiple command arguments to the setup.py
script:
$ python setup.py clean test lint sdist build_doc upload
You may need additional dependencies if a tool doesn't provide a distutils
command, for example pylint
doesn't, so you need setuptools-lint
package for python setup.py lint
to work.
You can declare an alias for a command set in a similar way you do this with a Node project. Create a setup.cfg
file beside your setup.py
and add the alias:
# setup.cfg
[aliases]
ci=clean test lint sdist build_doc upload
Now the command above is the same as
$ python setup.py ci
As for the other requirements, probably Pipenv
is the tool most comparable to node
. It has neat features like automatic creation and activation of project-specific virtual environment, installation of packages from Pipfile
, locking of dependencies versions (similar to shrinkwrap
command), etc.
You can also write custom commands and bind them in your setup script. Example for an ls
command that runs ls -l
:
from distutils.core import Command
from setuptools import setup
class Ls(Command):
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
self.spawn(['ls', '-l'])
setup(
name='spam',
version='0.1',
author='nobody',
author_email='[email protected]',
packages=[],
cmdclass={'ls': Ls,},
)
Now run python setup.py ls
to invoke the new command:
$ python setup.py ls
running ls
ls -l
total 8
drwx------ 3 hoefling wheel 96 16 Dez 19:47
com.apple.launchd.1X84ONyuu4
drwx------ 3 hoefling wheel 96 16 Dez 19:47
com.apple.launchd.XbjjBY44Mf
drwxr-xr-x 2 root wheel 64 16 Dez 19:47 powerlog
-rw-r--r-- 1 hoefling wheel 405 16 Dez 19:50 setup.py
Upvotes: 2
Reputation:
If you are okay with using a library for this, paver is an option. The documentation here states a way to use paver without changing the way setuptools are used in a project.
Upvotes: 0