2010-11-11 65 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