py2app在构建期间拾取包的.git子目录

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)

更新#2

我发布了自己的答案,它在distutils上做了一个monkeypatch.它的丑陋而不是首选,但直到有人能给我一个更好的解决方案,我想这就是我所拥有的.

jdi*_*jdi 3

我正在添加我自己问题的答案,以记录迄今为止我发现的唯一有效的方法。我的方法是在创建目录或复制文件时使用 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)在我的项目中重用。