如何在setup.py中执行(安全)bash shell命令?

时间:2015-01-14 19:04:12

标签: python setuptools nunjucks

我使用nunjucks来模拟python项目中的前端。 Nunjucks模板必须在生产中预编译。我不会在nunjucks模板中使用扩展或异步过滤器。我更喜欢使用nunjucks-precompile命令(通过npm提供)将整个模板目录扫描到templates.js,而不是使用grunt-task来监听模板的更改。

我们的想法是让nunjucks-precompile --include ["\\.tmpl$"] path/to/templates > templates.js命令在setup.py中执行,这样我就可以简单地搭载我们的部署脚本'定期执行。

我发现a setuptools overridea distutils scripts argument可能是正确的目的,但我不确定这是最简单的执行方法。

另一种方法是使用subprocess直接在setup.py中执行命令,但是我已经被警告过了(相当先发制人的恕我直言)。我不太明白为什么不这样做。

有什么想法吗?誓?确认?

更新(04/2015): - 如果您没有nunjucks-precompile命令,只需使用节点包管理器安装nunjucks就像这样:

$ npm install nunjucks

2 个答案:

答案 0 :(得分:3)

赦免快速的自我回答。我希望这可以帮助那些人在那里。我想分享这个,因为我已经找到了一个我满意的解决方案。

这是一个安全且基于Peter Lamut's write-up的解决方案。请注意,这在子进程调用中 not 使用shell = True。您可以绕过python部署系统上的grunt-task要求,也可以使用它来进行混淆和JS打包。

from setuptools import setup
from setuptools.command.install import install
import subprocess
import os

class CustomInstallCommand(install):
    """Custom install setup to help run shell commands (outside shell) before installation"""
    def run(self):
        dir_path = os.path.dirname(os.path.realpath(__file__))
        template_path = os.path.join(dir_path, 'src/path/to/templates')
        templatejs_path = os.path.join(dir_path, 'src/path/to/templates.js')
        templatejs = subprocess.check_output([
            'nunjucks-precompile',
            '--include',
            '["\\.tmpl$"]',
            template_path
        ])
        f = open(templatejs_path, 'w')
        f.write(templatejs)
        f.close()
        install.run(self)

setup(cmdclass={'install': CustomInstallCommand},
      ...
     )

答案 1 :(得分:0)

我认为链接here封装了您要实现的目标。