jdi*_*jdi 7 python macos distutils setuptools py2app
我们在我们的工厂广泛使用py2app来生成自包含的.app包,以便在没有依赖性问题的情况下轻松进行内部部署.我最近注意到的,并且不知道它是如何开始的,是在构建.app时,py2app开始包含我们主库的.git目录.
例如,commonLib是我们的根python库包,它是一个git repo.在这个包下面是各种子包,如数据库,实用程序等.
commonLib/
|- .git/ # because commonLib is a git repo
|- __init__.py
|- database/
|- __init__.py
|- utility/
|- __init__.py
# ... etc
Run Code Online (Sandbox Code Playgroud)
在一个给定的项目中,比如Foo,我们将进行导入,就像from commonLib import xyz使用我们的通用软件包一样.通过py2app构建类似于:python setup.py py2app
所以我最近看到的问题是,当为项目Foo构建一个应用程序时,我会看到它包含commonLib/.git /中的所有内容到应用程序中,这是额外的膨胀.py2app有一个排除选项,但似乎只适用于python模块.我不知道要排除.git子目录需要什么,或者实际上是什么原因导致它被包含在第一位.
有没有人在使用git repo的python包导入时遇到过这种情况?我们在每个项目的setup.py文件中没有任何变化,而且commonLib一直是一个git repo.所以我唯一可以想到的变量就是py2app及其deps的版本,这些版本显然随着时间的推移而升级.
编辑
我正在使用最新的py2app 0.6.4.另外,我的setup.py最初是从py2applet生成的,但是之后已经手动配置并作为模板复制到每个新项目.我正在为这些项目的每一个使用PyQt4/sip,所以它也让我想知道它是否与其中一个食谱有关?
从第一个答案开始,我尝试使用各种exclude_package_data设置组合来解决这个问题.似乎没有任何东西强制排除.git目录.以下是我的setup.py文件通常如下所示的示例:
from setuptools import setup
from myApp import VERSION
appname = 'MyApp'
APP = ['myApp.py']
DATA_FILES = []
OPTIONS = {
'includes': 'atexit, sip, PyQt4.QtCore, PyQt4.QtGui',
'strip': True,
'iconfile':'ui/myApp.icns',
'resources':['src/myApp.png'],
'plist':{
'CFBundleIconFile':'ui/myApp.icns',
'CFBundleIdentifier':'com.company.myApp',
'CFBundleGetInfoString': appname,
'CFBundleVersion' : VERSION,
'CFBundleShortVersionString' : VERSION
}
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
Run Code Online (Sandbox Code Playgroud)
我尝试过这样的事情:
setup(
...
exclude_package_data = { 'commonLib': ['.git'] },
#exclude_package_data = { '': ['.git'] },
#exclude_package_data = { 'commonLib/.git/': ['*'] },
#exclude_package_data = { '.git': ['*'] },
...
)
Run Code Online (Sandbox Code Playgroud)
我发布了自己的答案,它在distutils上做了一个monkeypatch.它的丑陋而不是首选,但直到有人能给我一个更好的解决方案,我想这就是我所拥有的.
我正在添加我自己问题的答案,以记录迄今为止我发现的唯一有效的方法。我的方法是在创建目录或复制文件时使用 Monkeypatch distutils 忽略某些模式。这确实不是我想做的,但就像我说的,这是迄今为止唯一有效的方法。
## setup.py ##
import re
# file_util has to come first because dir_util uses it
from distutils import file_util, dir_util
def wrapper(fn):
def wrapped(src, *args, **kwargs):
if not re.search(r'/\.git/?', src):
fn(src, *args, **kwargs)
return wrapped
file_util.copy_file = wrapper(file_util.copy_file)
dir_util.mkpath = wrapper(dir_util.mkpath)
# now import setuptools so it uses the monkeypatched methods
from setuptools import setup
Run Code Online (Sandbox Code Playgroud)
希望有人对此发表评论并告诉我一种更高级别的方法来避免这样做。但到目前为止,我可能会将其包装到一个实用方法中,以便exclude_data_patterns(re_pattern)在我的项目中重用。