【问题标题】:Python setup.py to run shell scriptPython setup.py 运行 shell 脚本
【发布时间】:2013-07-27 02:38:43
【问题描述】:

在创建 Python 包时,我需要在“sdist”阶段运行我自己的脚本。 我写了以下脚本。你知道更好的方法吗?您能否推荐一个更好的或链接到 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,
)

【问题讨论】:

    标签: python setuptools


    【解决方案1】:

    虽然这来得太晚了,但这里有一个解决方案建议。

    基本上,它只是将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等。

    【讨论】:

      【解决方案2】:

      也许可以试试 distutils 我认为它比 setuptools 更新。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 2018-08-15
      • 1970-01-01
      • 2022-01-06
      • 2015-10-15
      相关资源
      最近更新 更多