Python setup.py to run shell script

I need to run my own script during the sdist phase when creating a Python package. I wrote the following script. Do you know a better approach? Could you recommend a better link to the official documentation on setuptools, where this point was explained?

import subprocess import sys from setuptools import setup, find_packages, os if 'sdist' in sys.argv: cwd = os.getcwd() os.chdir('website/static/stylesheets/') result = subprocess.call("scss --update --compass ./*.scss", shell=True) if result != 0: exit(1) os.chdir(cwd) setup(name = "site", author="Vladimir Ignatev", author_email=" mail@gmail.com ", version="0.1", packages=find_packages(), include_package_data=True, zip_safe=True, ) 
+7
python setuptools
source share
2 answers

Although this happens quite late, here is a suggestion for a solution.

Basically, this is just a subclassification of the distutils ' sdist with the addition of user logic and its registration in the configuration function. Unfortunately, the official documentation for this topic is a bit vague and concise ; The Distutils extension provides at least a tiny example to get you started. I was much better off reading the module code in distutils.command to see how the actual commands are implemented.

To execute an arbitrary command, you can use the distutils.cmd.Command::spawn method, which executes the input string passed, raising a DistutilsExecError if the command exit code is non-zero:

 from distutils.command.sdist import sdist as sdist_orig from distutils.errors import DistutilsExecError from setuptools import setup class sdist(sdist_orig): def run(self): try: self.spawn(['ls', '-l']) except DistutilsExecError: self.warn('listing directory failed') super().run() setup(name='spam', version='0.1', packages=[], cmdclass={ 'sdist': sdist } ) 

Running the setup script above gives:

 $ python setup.py sdist running sdist ls -l total 24 -rw-r--r-- 1 hoefling staff 52 23 Dez 19:06 MANIFEST drwxr-xr-x 3 hoefling staff 96 23 Dez 19:06 dist -rw-r--r-- 1 hoefling staff 484 23 Dez 19:07 setup.py running check ... writing manifest file 'MANIFEST' creating spam-0.1 making hard links in spam-0.1... hard linking setup.py -> spam-0.1 Creating tar archive removing 'spam-0.1' (and everything under it) 

Team reuse

Here is a (albeit simplified) real-life example of the team that we use in our projects, which is used around NodeJS projects and calls yarn :

 import distutils import os import pathlib import setuptools _YARN_CMD_SEP = ';' _HELP_MSG_SUBCMD = ( 'yarn subcommands to execute (separated ' 'by {})'.format(_YARN_CMD_SEP) ) _HELP_MSG_PREFIX = ( 'path to directory containing package.json. ' 'If not set, current directory is assumed.' ) class yarn(setuptools.Command): description = ('runs yarn commands. Assumes yarn is ' 'already installed by the user.') user_options = [ ('subcommands=', None, _HELP_MSG_SUBCMD), ('prefix=', None, _HELP_MSG_PREFIX), ] def initialize_options(self) -> None: self.subcommands = [] self.prefix = None # type: pathlib.Path def finalize_options(self) -> None: self.subcommands = [ cmd.strip() for cmd in str(self.subcommands).split(self._YARN_CMD_SEP) ] self.prefix = pathlib.Path(self.prefix) if self.prefix else pathlib.Path() def run(self) -> None: cwd = pathlib.Path().absolute() os.chdir(str(self.prefix.absolute())) # change to prefix dir for cmd in self.subcommands: self.announce('running yarn {} ...'.format(cmd), level=distutils.log.INFO) self.spawn(['yarn'] + cmd.split(' ')) os.chdir(str(cwd)) # change back to our previous dir 

Usage example:

 $ python setup.py yarn --prefix=. --subcommands="add leftpad; remove leftpad" running yarn running yarn add leftpad ... yarn add leftpad yarn add v1.3.2 warning package.json: No license field warning No license field [1/4] 🔍 Resolving packages... [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... [4/4] 📃 Building fresh packages... success Saved lockfile. success Saved 1 new dependency. └─ leftpad@0.0.1 warning No license field ✨ Done in 0.33s. running yarn remove leftpad ... yarn remove leftpad yarn remove v1.3.2 warning package.json: No license field [1/2] Removing module leftpad... [2/2] Regenerating lockfile and installing missing dependencies... warning No license field success Uninstalled packages. ✨ Done in 0.13s. 

You can also use yarn in your command chain like every other command: python setup.py yarn test sdist , etc.

+2
source share

Maybe try distutils I think it is later than setuptools.

-2
source share

All Articles