本文介绍了通过Python setuptools获取远程git分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经坐了一会儿,现在是这个问题。你知道我是否能够以任何方式在setup.py中引用git分支? '@'符号应该这样做吗?或者它仅用于标记和提交?

 #setup.py 
... $ b $这是我尝试做的一个例子。 b install_requires = ['Django == 1.5.11']
dependency_links = ['git + https://github.com/django-nonrel/[email protected]#egg=Django-1.5.11 ']
...
#python setup.py开发
运行开发
运行egg_info
...
mypackage的处理依赖关系
搜索Django == 1.5.11
最佳匹配:Django 1.5.11
将git clone从https://github.com/django-nonrel/django.git改为c:\ users \ my_user_name\appdata\local\temp\easy_install-ci3vh1\[email protected]
检出nonrel-1.5
致命错误:不是git存储库(或任何父目录):.git

当我没有引用任何分支时,上面的代码没有问题:

  git + https://github.com/django-nonrel/django.git#egg=Django 

当我用pip运行它时:

  pip install git + https://github.com/django-nonrel/[email protected] 

为了达到目的,我包含了软件包名称,因此您可以查看他们的git repo安装程序。我没有要求从git安装软件包的替代方法,因为我知道它们。就好像可以在setup.py中引用分支一样。
在此先感谢。

解决方案

我正在深入研究setuptools实现(保留最新的镜像以方便浏览),它看起来像我一样发现问题在哪里。如果我们看一下负责下载package_index.py中定义的git repos的函数:

  def _download_git(self,url,filename) :
filename = filename.split('#',1)[0]
url,rev = self._vcs_split_rev_from_url(url,pop_prefix = True)

self.info 做git克隆从%s到%s,url,filename)
os.system(git clone --quiet%s%s%(url,filename))

如果rev不是None:
self.info(检出%s,rev)
os.system((cd%s&&&git checkout --quiet%s)% (
文件名,
rev,
))

返回文件名

我们可以看到它首先将其克隆到某个目录(通常是系统临时文件),然后是cd git checkout分支。不幸的是,最近我不得不在Windows上工作,我讨厌这个问题(长期Arch Linux!),并且这个checkout命令的问题在于该系统上的cd不会自动切换驱动器。所以如果你的软件包位于另一个分区/驱动器而不是你的临时目录中,它就不会起作用。我检查了将它改正为:

 (cd / d%s&&&git checkout --quiet%s)

解决了这个问题。尽管这是系统特定的,所以我们(可能)不想让PR去setuptools家伙修改它。相反,我所做的是在我的包文件夹中创建一个临时目录,并添加

  import tempfile 
tempfile.tempdir = os.getcwd()+\\temp\\

到我的设置。 py,它临时更改easy_install的临时目录。这是因为我知道setuptools使用easy_install,而easy_install使用tempfile来获取临时目录的位置。这是一个很好的解决方案,我坚持使用它,但为了传播信息,我还要提到另一件我正在尝试创建的临时系统别名cd到cd / d。在Windows上,这是doskey命令。不幸的是,这是一个本地命令,不会传播到使用os.system()创建的子进程。全局设置这样的别名虽然是一种痛苦,你不想修改潜在用户的系统注册表来实现它。


I've been sitting on this for a while now and here is the question. Do you know if I'm able to reference a git branch in setup.py in any way? Is '@' sign supposed to do that? Or is it used solely for tags and commits? Here is an example of what I was trying to do.

# setup.py
...
install_requires=['Django==1.5.11']
dependency_links=['git+https://github.com/django-nonrel/[email protected]#egg=Django-1.5.11']
...
#python setup.py develop
running develop
running egg_info
...
Processing dependencies for mypackage
Searching for Django==1.5.11
Best match: Django 1.5.11
Doing git clone from https://github.com/django-nonrel/django.git to c:\users\my_user_name\appdata\local\temp\easy_install-ci3vh1\[email protected]
Checking out nonrel-1.5
fatal: Not a git repository (or any of the parent directories): .git

Above works without a problem when I'm not referencing any branch:

git+https://github.com/django-nonrel/django.git#egg=Django

And when I run it with pip:

pip install git+https://github.com/django-nonrel/[email protected]

I included the package name for purpose, so you can look at their git repo setup. I'm not asking for the alternative ways of installing packages from git, as I'm aware of them. Just if it is possible to reference a branch in setup.py.Thanks in advance.

解决方案

I was digging down through the setuptools implementation (https://github.com/jaraco/setuptools keeps an up-to-date mirror for ease of browsing) and it looks like I've found where the problem is. If we look at the function responsible for downloading git repos defined in package_index.py:

    def _download_git(self, url, filename):
    filename = filename.split('#',1)[0]
    url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)

    self.info("Doing git clone from %s to %s", url, filename)
    os.system("git clone --quiet %s %s" % (url, filename))

    if rev is not None:
        self.info("Checking out %s", rev)
        os.system("(cd %s && git checkout --quiet %s)" % (
            filename,
            rev,
        ))

    return filename

we can see it's first cloning it to some directory (usually system temp) and then "cd git checkout" 'ing the branch. Unfortunately recently I'm forced to work on Windows, which I hate (long live Arch Linux!), and the problem with this checkout command is that cd on this system doesn't automatically switch the drive. So it's not going to work if your package is located on the other partition/drive than your temp directory. I checked that correcting it to:

(cd /d %s && git checkout --quiet %s)

solves the problem. This is system specific though, so we (probably) don't want to do PR to setuptools guys to modify it. Instead what I did was to create a temp directory in my package folder and add

import tempfile
tempfile.tempdir=os.getcwd()+"\\temp\\"

to my setup.py, which temporary changes the temp directory of easy_install. That's because I know that setuptools uses easy_install and that easy_install uses tempfile to obtain the location of temp dir. This is a good solution and I'm sticking with it, but for the sake of spreading information, I'd also mention that another thing I was trying was to create a temporary system alias for "cd" to "cd /d". On windows this is the doskey command. Unfortunately this is a local command and doesn't spread to subprocesses created with os.system(). Setting such alias globally though is a pain and you don't want to modify system registry of potential users to achieve that.

这篇关于通过Python setuptools获取远程git分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 20:53