2010-11-11 105 views
21

我想让pip在GitHub上安装一个依赖项,当用户发出命令安装原始软件时,也可以从GitHub上的源码安装。这些软件包都不在PyPi上(并且永远不会)。安装时,Pip可否安装setup.py中未指定的依赖项?

用户发出命令:

pip -e git+https://github.com/Lewisham/[email protected]#egg=cvsanaly 

此回购有requirements.txt文件,用在GitHub上另一依赖性:

-e git+https://github.com/Lewisham/repositoryhandler#egg=repositoryhandler 

我想是单个命令一个用户可以发出安装原始包,找到需求文件,然后安装依赖关系。

回答

36

This answer帮助我解决了你正在谈论的同一问题。

似乎没有一种简单的方法让setup.py直接使用需求文件来定义它的依赖关系,但是可以将相同的信息放入setup.py本身。

我有这个requirements.txt:

PIL 
-e git://github.com/gabrielgrant/django-ckeditor.git#egg=django-ckeditor 

但安装该requirements.txt的含包时,要求由PIP忽略。

这setup.py似乎强迫PIP进入安装依赖关系(包括Django的CKEditor的我github上的版本):

from setuptools import setup 

setup(
    name='django-articles', 
    ..., 
    install_requires=[ 
     'PIL', 
     'django-ckeditor>=0.9.3', 
    ], 
    dependency_links = [ 
     'http://github.com/gabrielgrant/django-ckeditor/tarball/master#egg=django-ckeditor-0.9.3', 
    ] 
) 

编辑:

This answer还包含了一些有用的信息。

需要指定版本作为“#egg = ...”的一部分,以确定该链接上的哪个版本的软件包可用。 但是请注意,如果你总是希望依靠你的最新版本,您可以设置install_requires的版本 dev,dependency_links和其他包的setup.py

编辑:使用dev作为版本ISN根据下面的评论,这不是一个好主意。

+3

与“开发”的伎俩只适用于第一次,而不是随后的时间。 setup.py只检查“dev”字符串作为自己的版本 – DanEEStar 2012-07-05 15:39:17

+2

@DanEEStar没错。一旦安装了包的_dev_版本'setuptools'就会考虑满足要求。正如在[链接的答案](http://stackoverflow.com/a/2163919/396967)中所演示的那样,您需要同步更新*全部3个地方中的软件包版本*:依赖项的'setup.py'和'install_requires'和'dependency_links' - 不太实际。 – kynan 2012-12-17 02:11:05

+1

是的@DanEEStar你是对的。我已经编辑出使用'dev'版本的建议。谢谢你们两位! – 2013-02-21 18:28:06

12

这是我用来从需求文件生成install_requiresdependency_links的小脚本。

import os 
import re 

def which(program): 
    """ 
    Detect whether or not a program is installed. 
    Thanks to http://stackoverflow.com/a/377028/70191 
    """ 
    def is_exe(fpath): 
     return os.path.exists(fpath) and os.access(fpath, os.X_OK) 

    fpath, _ = os.path.split(program) 
    if fpath: 
     if is_exe(program): 
      return program 
    else: 
     for path in os.environ['PATH'].split(os.pathsep): 
      exe_file = os.path.join(path, program) 
      if is_exe(exe_file): 
       return exe_file 

    return None 

EDITABLE_REQUIREMENT = re.compile(r'^-e (?P<link>(?P<vcs>git|svn|hg|bzr).+#egg=(?P<package>.+)-(?P<version>\d(?:\.\d)*))$') 

install_requires = [] 
dependency_links = [] 

for requirement in (l.strip() for l in open('requirements')): 
    match = EDITABLE_REQUIREMENT.match(requirement) 
    if match: 
     assert which(match.group('vcs')) is not None, \ 
      "VCS '%(vcs)s' must be installed in order to install %(link)s" % match.groupdict() 
     install_requires.append("%(package)s==%(version)s" % match.groupdict()) 
     dependency_links.append(match.group('link')) 
    else: 
     install_requires.append(requirement) 
1

这是回答您的问题吗?

setup(name='application-xpto', 
    version='1.0', 
    author='me,me,me', 
    author_email='[email protected]', 
    packages=find_packages(), 
    include_package_data=True, 
    description='web app', 
    install_requires=open('app/requirements.txt').readlines(), 
) 
+2

open('app/requirements.txt')。readlines()仅在requirements.txt只包含“普通”版本规范而不包含URL时才起作用。这些将需要像Simon Charette的回答那样,在'dependency_links'中被拆分出来。 – kynan 2012-12-17 02:13:26