我需要在'sdist'阶段运行我自己的脚本,同时创建Python包。 我写了以下脚本。你知道更好的方法吗?您能否推荐更好的一个或链接到setuptools上的官方文档,其中已经解释了这个时刻?
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,
)
答案 0 :(得分:3)
虽然这已经很晚了,但这是一个解决方案提案。
基本上,它只是将distutils
' sdist
命令,添加自定义逻辑并在设置函数中注册。 Unfortunately, the official documentation to this topic is kind of vague and laconic; Extending Distutils至少提供了一个很小的例子。我发现阅读distutils.command
包中的模块代码以了解实际命令是如何实现的更好。
要执行任意命令,您可以使用执行传递的输入字符串的方法distutils.cmd.Command::spawn
,如果命令的退出代码不为零,则引发DistutilsExecError
:
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
}
)
运行上面的安装脚本会产生:
$ 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)
这是(尽管简化)我们在项目中使用的命令的实际示例,这些命令用于NodeJS项目并调用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
使用示例:
$ 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.
您还可以在命令链中使用yarn
作为其他命令:python setup.py yarn test sdist
等。
答案 1 :(得分:-3)
也许尝试distutils
我认为它比setuptools更新。