--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/virtualenv/res/lib/lib_create_env.py Tue Mar 29 13:33:43 2011 +0200
@@ -0,0 +1,292 @@
+import sys
+import os
+import os.path
+import shutil
+import tarfile
+import zipfile
+import urllib
+import platform
+import patch
+
+join = os.path.join
+system_str = platform.system()
+
+
+URLS = {
+ 'DISTRIBUTE': {'setup': 'distribute', 'url':'http://pypi.python.org/packages/source/d/distribute/distribute-0.6.14.tar.gz', 'local':"distribute-0.6.14.tar.gz"},
+ 'DJANGO': {'setup': 'django', 'url': 'http://www.djangoproject.com/download/1.2.4/tarball/', 'local':"Django-1.2.4.tar.gz"},
+ 'JOGGING': {'setup': 'jogging', 'url': 'http://github.com/zain/jogging/tarball/v0.2.2', 'local':"jogging-0.2.2.tar.gz"},
+ 'DJANGO-EXTENSIONS': { 'setup': 'django-extensions', 'url':'https://github.com/django-extensions/django-extensions/tarball/0.6', 'local':"django-extensions-0.6.tar.gz"},
+ 'DJANGO-REGISTRATION': { 'setup': 'django-registration', 'url':'http://bitbucket.org/ubernostrum/django-registration/get/tip.tar.gz', 'local':"django-registration.tar.gz"},
+ 'DJANGO-TAGGING': { 'setup': 'django-tagging', 'url':'http://django-tagging.googlecode.com/files/django-tagging-0.3.1.tar.gz', 'local':"django-tagging-0.3.1.tar.gz"},
+ 'DJANGO-PISTON': { 'setup': 'django-piston', 'url':"django-piston-0.2.2-modified.tar.gz", 'local':"django-piston-0.2.2-modified.tar.gz"},
+ 'OAUTH2': { 'setup': 'python-oauth2', 'url':"python-oauth2-1.2.1-modified.tar.gz", 'local':"python-oauth2-1.2.1-modified.tar.gz"},
+ 'HTTPLIB2': { 'setup': 'python-oauth2', 'url':'http://httplib2.googlecode.com/files/httplib2-0.6.0.tar.gz', 'local':"httplib2-0.6.0.tar.gz"},
+ 'DJANGO-OAUTH-PLUS': { 'setup': 'django-oauth-plus', 'url':'http://bitbucket.org/david/django-oauth-plus/get/f314f018e473.gz', 'local':"django-oauth-plus.tar.gz"},
+ 'MYSQL': { 'setup': 'mysql-python', 'url': 'http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.3/MySQL-python-1.2.3.tar.gz/download', 'local':"MySQL-python-1.2.3.tar.gz"},
+ 'SETUPTOOLS-HG': { 'setup':'mercurial_hg', 'url':'http://pypi.python.org/packages/source/s/setuptools_hg/setuptools_hg-0.2.tar.gz', 'local':"setuptools_hg-0.2.tar.gz"},
+ 'MERCURIAL': {'setup':'mercurial', 'url':'http://pypi.python.org/packages/source/d/mercurial/mercurial-1.7.5.tar.gz', 'local':"mercurial-1.7.5.tar.gz"}
+}
+
+if system_str == 'Windows':
+ URLS.update({
+ 'PSYCOPG2': {'setup': 'psycopg2','url': 'psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip', 'local':"psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip"},
+ 'JCC': {'setup': 'http://pylucene-win32-binary.googlecode.com/files/JCC-2.6-py2.6-win32.egg', 'local':"JCC-2.6-py2.6-win32.egg"},
+ 'PYLUCENE': {'setup': 'http://pylucene-win32-binary.googlecode.com/files/lucene-3.0.2-py2.6-win32.egg', 'local':"lucene-3.0.2-py2.6-win32.egg"},
+ 'PIL': {'setup': 'pil', 'url': 'http://effbot.org/media/downloads/PIL-1.1.7.win32-py2.6.exe', 'local':"PIL-1.1.7.win32-py2.6.exe"},
+ 'LXML': {'setup': 'lxml', 'url': 'http://pypi.python.org/packages/2.6/l/lxml/lxml-2.2.8-py2.6-win32.egg', 'local':"lxml-2.2.8-py2.6-win32.egg"}
+ })
+else:
+ URLS.update({
+ 'PSYCOPG2': {'setup': 'psycopg2','url': 'http://initd.org/psycopg/tarballs/PSYCOPG-2-3/psycopg2-2.3.2.tar.gz', 'local':"psycopg2-2.3.2.tar.gz"},
+ 'PYLUCENE': {'setup': 'http://apache.crihan.fr/dist/lucene/pylucene/pylucene-3.0.3-1-src.tar.gz', 'url': 'http://apache.crihan.fr/dist/lucene/pylucene/pylucene-3.0.3-1-src.tar.gz', 'local':"pylucene-3.0.3-1-src.tar.gz"},
+ 'PIL': {'setup': 'pil', 'url': 'http://effbot.org/downloads/Imaging-1.1.7.tar.gz', 'local':"Imaging-1.1.7.tar.gz"},
+ 'LXML': {'setup': 'lxml', 'url':"lxml_2.2.8.tar.gz", 'local':"lxml-2.2.8.tar.gz"}
+ })
+
+
+
+class ResourcesEnv(object):
+
+ def __init__(self, src_base, urls, normal_installs):
+ self.src_base = src_base
+ self.URLS = {}
+ self.__init_url(urls)
+ self.NORMAL_INSTALL = normal_installs
+
+ def get_src_base_path(self, fpath):
+ return os.path.abspath(os.path.join(self.src_base, fpath)).replace("\\","/")
+
+ def __add_package_def(self, key, setup, url, local):
+ self.URLS[key] = {'setup':setup, 'url':url, 'local':self.get_src_base_path(local)}
+
+ def __init_url(self, urls):
+ for key, url_dict in urls.items():
+ url = url_dict['url']
+ if not url.startswith("http://"):
+ url = self.get_src_base_path(url)
+ self.__add_package_def(key, url_dict["setup"], url, url_dict["local"])
+
+def ensure_dir(dir, logger):
+ if not os.path.exists(dir):
+ logger.notify('Creating directory %s' % dir)
+ os.makedirs(dir)
+
+def extend_parser(parser):
+ parser.add_option(
+ '--index-url',
+ metavar='INDEX_URL',
+ dest='index_url',
+ default='http://pypi.python.org/simple/',
+ help='base URL of Python Package Index')
+ parser.add_option(
+ '--type-install',
+ metavar='type_install',
+ dest='type_install',
+ default='local',
+ help='type install : local, url, setup')
+ parser.add_option(
+ '--ignore-packages',
+ metavar='ignore_packages',
+ dest='ignore_packages',
+ default=None,
+ help='list of comma separated keys for package to ignore')
+
+def adjust_options(options, args):
+ pass
+
+
+def install_pylucene(option_str, extra_env, res_source_key, home_dir, tmp_dir, src_dir, res_env, logger, call_subprocess, filter_python_develop):
+
+ logger.notify("Get Pylucene from %s " % res_env.URLS['PYLUCENE'][res_source_key])
+ pylucene_src = os.path.join(src_dir,"pylucene.tar.gz")
+ if res_source_key == 'local':
+ shutil.copy(res_env.URLS['PYLUCENE'][res_source_key], pylucene_src)
+ else:
+ urllib.urlretrieve(res_env.URLS['PYLUCENE'][res_source_key], pylucene_src)
+ tf = tarfile.open(pylucene_src,'r:gz')
+ pylucene_base_path = os.path.join(src_dir,"pylucene")
+ logger.notify("Extract Pylucene to %s " % pylucene_base_path)
+ tf.extractall(pylucene_base_path)
+ tf.close()
+
+ pylucene_src_path = os.path.join(pylucene_base_path, os.listdir(pylucene_base_path)[0])
+ jcc_src_path = os.path.abspath(os.path.join(pylucene_src_path,"jcc"))
+
+ #install jcc
+
+ #patch for linux
+ if system_str == 'Linux' :
+ olddir = os.getcwd()
+ patch_dest_path = os.path.join(lib_dir,'site-packages','setuptools-0.6c11-py'+'%s.%s' % (sys.version_info[0], sys.version_info[1])+'.egg')
+ if os.path.isfile(patch_dest_path):
+ # must unzip egg
+ # rename file and etract all
+ shutil.move(patch_dest_path, patch_dest_path + ".zip")
+ zf = zipfile.ZipFile(patch_dest_path + ".zip",'r')
+ zf.extractall(patch_dest_path)
+ os.remove(patch_dest_path + ".zip")
+ logger.notify("Patch jcc : %s " % (patch_dest_path))
+ os.chdir(patch_dest_path)
+ p = patch.fromfile(os.path.join(jcc_src_path,"jcc","patches","patch.43.0.6c11"))
+ p.apply()
+ os.chdir(olddir)
+
+ logger.notify("Install jcc")
+ call_subprocess([os.path.abspath(os.path.join(home_dir, 'bin', 'python')), 'setup.py', 'install'],
+ cwd=jcc_src_path,
+ filter_stdout=filter_python_develop,
+ show_stdout=True)
+ #install pylucene
+
+ logger.notify("Install pylucene")
+ #modify makefile
+ makefile_path = os.path.join(pylucene_src_path,"Makefile")
+ logger.notify("Modify makefile %s " % makefile_path)
+ shutil.move( makefile_path, makefile_path+"~" )
+
+ destination= open( makefile_path, "w" )
+ source= open( makefile_path+"~", "r" )
+ destination.write("PREFIX_PYTHON="+os.path.abspath(home_dir)+"\n")
+ destination.write("ANT=ant\n")
+ destination.write("PYTHON=$(PREFIX_PYTHON)/bin/python\n")
+
+ if system_str == "Darwin":
+ if sys.version_info >= (2,6):
+ destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\n")
+ else:
+ destination.write("JCC=$(PYTHON) -m jcc --shared --arch x86_64 --arch i386\n")
+ destination.write("NUM_FILES=2\n")
+ elif system_str == "Windows":
+ destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\n")
+ destination.write("NUM_FILES=2\n")
+ else:
+ if sys.version_info >= (2,6) and sys.version_info <= (2,7):
+ destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared\n")
+ else:
+ destination.write("JCC=$(PYTHON) -m jcc --shared\n")
+ destination.write("NUM_FILES=2\n")
+ for line in source:
+ destination.write( line )
+ source.close()
+ destination.close()
+ os.remove(makefile_path+"~" )
+
+ logger.notify("pylucene make")
+ call_subprocess(['make'],
+ cwd=os.path.abspath(pylucene_src_path),
+ filter_stdout=filter_python_develop,
+ show_stdout=True)
+
+ logger.notify("pylucene make install")
+ call_subprocess(['make', 'install'],
+ cwd=os.path.abspath(pylucene_src_path),
+ filter_stdout=filter_python_develop,
+ show_stdout=True)
+
+
+def install_psycopg2(option_str, extra_env, res_source_key, home_dir, tmp_dir, src_dir, res_env, logger, call_subprocess, filter_python_develop):
+ psycopg2_src = os.path.join(src_dir,"psycopg2.zip")
+ shutil.copy(res_env.URLS['PSYCOPG2'][res_source_key], psycopg2_src)
+ #extract psycopg2
+ zf = zipfile.ZipFile(psycopg2_src)
+ psycopg2_base_path = os.path.join(src_dir,"psycopg2")
+ zf.extractall(psycopg2_base_path)
+ zf.close()
+
+ psycopg2_src_path = os.path.join(psycopg2_base_path, os.listdir(psycopg2_base_path)[0])
+ shutil.copytree(os.path.join(psycopg2_src_path, 'psycopg2'), os.path.abspath(os.path.join(home_dir, 'Lib', 'psycopg2')))
+ shutil.copy(os.path.join(psycopg2_src_path, 'psycopg2-2.0.10-py2.6.egg-info'), os.path.abspath(os.path.join(home_dir, 'Lib', 'site-packages')))
+
+
+
+def lib_generate_install_methods(path_locations, src_base, Logger, call_subprocess, normal_installs, urls=None):
+
+ all_urls = URLS.copy()
+ if urls is not None:
+ all_urls.update(urls)
+
+ res_env = ResourcesEnv(src_base, all_urls, normal_installs)
+
+ def filter_python_develop(line):
+ if not line.strip():
+ return Logger.DEBUG
+ for prefix in ['Searching for', 'Reading ', 'Best match: ', 'Processing ',
+ 'Moving ', 'Adding ', 'running ', 'writing ', 'Creating ',
+ 'creating ', 'Copying ']:
+ if line.startswith(prefix):
+ return Logger.DEBUG
+ return Logger.NOTIFY
+
+
+ def normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir, res_env, logger, call_subprocess):
+ logger.notify("Install %s from %s with %s" % (key,res_env.URLS[key][res_source_key],method))
+ if method == 'pip':
+ if sys.platform == 'win32':
+ args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'pip')), 'install', '-E', os.path.abspath(home_dir), res_env.URLS[key][res_source_key]]
+ else:
+ args = [os.path.abspath(os.path.join(home_dir, 'bin', 'pip')), 'install', '-E', os.path.abspath(home_dir), res_env.URLS[key][res_source_key]]
+ if option_str :
+ args.insert(4,option_str)
+ call_subprocess(args,
+ cwd=os.path.abspath(tmp_dir),
+ filter_stdout=filter_python_develop,
+ show_stdout=True,
+ extra_env=extra_env)
+ else:
+ if sys.platform == 'win32':
+ args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'easy_install')), res_env.URLS[key][res_source_key]]
+ else:
+ args = [os.path.abspath(os.path.join(home_dir, 'bin', 'easy_install')), res_env.URLS[key][res_source_key]]
+ if option_str :
+ args.insert(1,option_str)
+ call_subprocess(args,
+ cwd=os.path.abspath(tmp_dir),
+ filter_stdout=filter_python_develop,
+ show_stdout=True,
+ extra_env=extra_env)
+
+
+ def after_install(options, home_dir):
+
+ global logger
+
+ verbosity = options.verbose - options.quiet
+ logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
+
+
+ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
+ base_dir = os.path.dirname(home_dir)
+ src_dir = os.path.join(home_dir, 'src')
+ tmp_dir = os.path.join(home_dir, 'tmp')
+ ensure_dir(src_dir, logger)
+ ensure_dir(tmp_dir, logger)
+ system_str = platform.system()
+
+ res_source_key = options.type_install
+
+ ignore_packages = []
+
+ if options.ignore_packages :
+ ignore_packages = options.ignore_packages.split(",")
+
+ logger.indent += 2
+ try:
+ for key, method, option_str, extra_env in res_env.NORMAL_INSTALL:
+ if key not in ignore_packages:
+ if callable(method):
+ method(option_str, extra_env, res_source_key, home_dir, tmp_dir, src_dir, res_env, logger, call_subprocess, filter_python_develop)
+ else:
+ normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir, res_env, logger, call_subprocess)
+
+ logger.notify("Clear source dir")
+ shutil.rmtree(src_dir)
+
+ finally:
+ logger.indent -= 2
+ script_dir = join(base_dir, bin_dir)
+ logger.notify('Run "%s Package" to install new packages that provide builds'
+ % join(script_dir, 'easy_install'))
+
+
+ return adjust_options, extend_parser, after_install
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/virtualenv/res/lib/patch.py Tue Mar 29 13:33:43 2011 +0200
@@ -0,0 +1,589 @@
+""" Patch utility to apply unified diffs
+
+ Brute-force line-by-line non-recursive parsing
+
+ Copyright (c) 2008-2010 anatoly techtonik
+ Available under the terms of MIT license
+
+ Project home: http://code.google.com/p/python-patch/
+
+
+ $Id: patch.py 76 2010-04-08 19:10:21Z techtonik $
+ $HeadURL: https://python-patch.googlecode.com/svn/trunk/patch.py $
+"""
+
+__author__ = "techtonik.rainforce.org"
+__version__ = "10.04"
+
+import copy
+import logging
+import re
+# cStringIO doesn't support unicode in 2.5
+from StringIO import StringIO
+from logging import debug, info, warning
+
+from os.path import exists, isfile, abspath
+from os import unlink
+
+
+#------------------------------------------------
+# Logging is controlled by "python_patch" logger
+
+debugmode = False
+
+logger = logging.getLogger("python_patch")
+loghandler = logging.StreamHandler()
+logger.addHandler(loghandler)
+
+debug = logger.debug
+info = logger.info
+warning = logger.warning
+
+#: disable library logging by default
+logger.setLevel(logging.CRITICAL)
+
+#------------------------------------------------
+
+
+def fromfile(filename):
+ """ Parse patch file and return Patch() object
+ """
+
+ info("reading patch from file %s" % filename)
+ fp = open(filename, "rb")
+ patch = Patch(fp)
+ fp.close()
+ return patch
+
+
+def fromstring(s):
+ """ Parse text string and return Patch() object
+ """
+
+ return Patch(
+ StringIO.StringIO(s)
+ )
+
+
+
+class HunkInfo(object):
+ """ Parsed hunk data container (hunk starts with @@ -R +R @@) """
+
+ def __init__(self):
+ self.startsrc=None #: line count starts with 1
+ self.linessrc=None
+ self.starttgt=None
+ self.linestgt=None
+ self.invalid=False
+ self.text=[]
+
+ def copy(self):
+ return copy.copy(self)
+
+# def apply(self, estream):
+# """ write hunk data into enumerable stream
+# return strings one by one until hunk is
+# over
+#
+# enumerable stream are tuples (lineno, line)
+# where lineno starts with 0
+# """
+# pass
+
+
+
+class Patch(object):
+
+ def __init__(self, stream=None):
+
+ # define Patch data members
+ # table with a row for every source file
+
+ #: list of source filenames
+ self.source=None
+ self.target=None
+ #: list of lists of hunks
+ self.hunks=None
+ #: file endings statistics for every hunk
+ self.hunkends=None
+
+ if stream:
+ self.parse(stream)
+
+ def copy(self):
+ return copy.copy(self)
+
+ def parse(self, stream):
+ """ parse unified diff """
+ self.source = []
+ self.target = []
+ self.hunks = []
+ self.hunkends = []
+
+ # define possible file regions that will direct the parser flow
+ header = False # comments before the patch body
+ filenames = False # lines starting with --- and +++
+
+ hunkhead = False # @@ -R +R @@ sequence
+ hunkbody = False #
+ hunkskip = False # skipping invalid hunk mode
+
+ header = True
+ lineends = dict(lf=0, crlf=0, cr=0)
+ nextfileno = 0
+ nexthunkno = 0 #: even if index starts with 0 user messages number hunks from 1
+
+ # hunkinfo holds parsed values, hunkactual - calculated
+ hunkinfo = HunkInfo()
+ hunkactual = dict(linessrc=None, linestgt=None)
+
+ fe = enumerate(stream)
+ for lineno, line in fe:
+
+ # analyze state
+ if header and line.startswith("--- "):
+ header = False
+ # switch to filenames state
+ filenames = True
+ #: skip hunkskip and hunkbody code until you read definition of hunkhead
+ if hunkbody:
+ # process line first
+ if re.match(r"^[- \+\\]", line):
+ # gather stats about line endings
+ if line.endswith("\r\n"):
+ self.hunkends[nextfileno-1]["crlf"] += 1
+ elif line.endswith("\n"):
+ self.hunkends[nextfileno-1]["lf"] += 1
+ elif line.endswith("\r"):
+ self.hunkends[nextfileno-1]["cr"] += 1
+
+ if line.startswith("-"):
+ hunkactual["linessrc"] += 1
+ elif line.startswith("+"):
+ hunkactual["linestgt"] += 1
+ elif not line.startswith("\\"):
+ hunkactual["linessrc"] += 1
+ hunkactual["linestgt"] += 1
+ hunkinfo.text.append(line)
+ # todo: handle \ No newline cases
+ else:
+ warning("invalid hunk no.%d at %d for target file %s" % (nexthunkno, lineno+1, self.target[nextfileno-1]))
+ # add hunk status node
+ self.hunks[nextfileno-1].append(hunkinfo.copy())
+ self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True
+ # switch to hunkskip state
+ hunkbody = False
+ hunkskip = True
+
+ # check exit conditions
+ if hunkactual["linessrc"] > hunkinfo.linessrc or hunkactual["linestgt"] > hunkinfo.linestgt:
+ warning("extra hunk no.%d lines at %d for target %s" % (nexthunkno, lineno+1, self.target[nextfileno-1]))
+ # add hunk status node
+ self.hunks[nextfileno-1].append(hunkinfo.copy())
+ self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True
+ # switch to hunkskip state
+ hunkbody = False
+ hunkskip = True
+ elif hunkinfo.linessrc == hunkactual["linessrc"] and hunkinfo.linestgt == hunkactual["linestgt"]:
+ self.hunks[nextfileno-1].append(hunkinfo.copy())
+ # switch to hunkskip state
+ hunkbody = False
+ hunkskip = True
+
+ # detect mixed window/unix line ends
+ ends = self.hunkends[nextfileno-1]
+ if ((ends["cr"]!=0) + (ends["crlf"]!=0) + (ends["lf"]!=0)) > 1:
+ warning("inconsistent line ends in patch hunks for %s" % self.source[nextfileno-1])
+ if debugmode:
+ debuglines = dict(ends)
+ debuglines.update(file=self.target[nextfileno-1], hunk=nexthunkno)
+ debug("crlf: %(crlf)d lf: %(lf)d cr: %(cr)d\t - file: %(file)s hunk: %(hunk)d" % debuglines)
+
+ if hunkskip:
+ match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line)
+ if match:
+ # switch to hunkhead state
+ hunkskip = False
+ hunkhead = True
+ elif line.startswith("--- "):
+ # switch to filenames state
+ hunkskip = False
+ filenames = True
+ if debugmode and len(self.source) > 0:
+ debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1]))
+
+ if filenames:
+ if line.startswith("--- "):
+ if nextfileno in self.source:
+ warning("skipping invalid patch for %s" % self.source[nextfileno])
+ del self.source[nextfileno]
+ # double source filename line is encountered
+ # attempt to restart from this second line
+ re_filename = "^--- ([^\t]+)"
+ match = re.match(re_filename, line)
+ # todo: support spaces in filenames
+ if match:
+ self.source.append(match.group(1).strip())
+ else:
+ warning("skipping invalid filename at line %d" % lineno)
+ # switch back to header state
+ filenames = False
+ header = True
+ elif not line.startswith("+++ "):
+ if nextfileno in self.source:
+ warning("skipping invalid patch with no target for %s" % self.source[nextfileno])
+ del self.source[nextfileno]
+ else:
+ # this should be unreachable
+ warning("skipping invalid target patch")
+ filenames = False
+ header = True
+ else:
+ if nextfileno in self.target:
+ warning("skipping invalid patch - double target at line %d" % lineno)
+ del self.source[nextfileno]
+ del self.target[nextfileno]
+ nextfileno -= 1
+ # double target filename line is encountered
+ # switch back to header state
+ filenames = False
+ header = True
+ else:
+ re_filename = "^\+\+\+ ([^\t]+)"
+ match = re.match(re_filename, line)
+ if not match:
+ warning("skipping invalid patch - no target filename at line %d" % lineno)
+ # switch back to header state
+ filenames = False
+ header = True
+ else:
+ self.target.append(match.group(1).strip())
+ nextfileno += 1
+ # switch to hunkhead state
+ filenames = False
+ hunkhead = True
+ nexthunkno = 0
+ self.hunks.append([])
+ self.hunkends.append(lineends.copy())
+ continue
+
+ if hunkhead:
+ match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line)
+ if not match:
+ if nextfileno-1 not in self.hunks:
+ warning("skipping invalid patch with no hunks for file %s" % self.target[nextfileno-1])
+ # switch to header state
+ hunkhead = False
+ header = True
+ continue
+ else:
+ # switch to header state
+ hunkhead = False
+ header = True
+ else:
+ hunkinfo.startsrc = int(match.group(1))
+ hunkinfo.linessrc = 1
+ if match.group(3): hunkinfo.linessrc = int(match.group(3))
+ hunkinfo.starttgt = int(match.group(4))
+ hunkinfo.linestgt = 1
+ if match.group(6): hunkinfo.linestgt = int(match.group(6))
+ hunkinfo.invalid = False
+ hunkinfo.text = []
+
+ hunkactual["linessrc"] = hunkactual["linestgt"] = 0
+
+ # switch to hunkbody state
+ hunkhead = False
+ hunkbody = True
+ nexthunkno += 1
+ continue
+ else:
+ if not hunkskip:
+ warning("patch file incomplete - %s" % filename)
+ # sys.exit(?)
+ else:
+ # duplicated message when an eof is reached
+ if debugmode and len(self.source) > 0:
+ debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1]))
+
+ info("total files: %d total hunks: %d" % (len(self.source), sum(len(hset) for hset in self.hunks)))
+
+
+ def apply(self):
+ """ apply parsed patch """
+
+ total = len(self.source)
+ for fileno, filename in enumerate(self.source):
+
+ f2patch = filename
+ if not exists(f2patch):
+ f2patch = self.target[fileno]
+ if not exists(f2patch):
+ warning("source/target file does not exist\n--- %s\n+++ %s" % (filename, f2patch))
+ continue
+ if not isfile(f2patch):
+ warning("not a file - %s" % f2patch)
+ continue
+ filename = f2patch
+
+ info("processing %d/%d:\t %s" % (fileno+1, total, filename))
+
+ # validate before patching
+ f2fp = open(filename)
+ hunkno = 0
+ hunk = self.hunks[fileno][hunkno]
+ hunkfind = []
+ hunkreplace = []
+ validhunks = 0
+ canpatch = False
+ for lineno, line in enumerate(f2fp):
+ if lineno+1 < hunk.startsrc:
+ continue
+ elif lineno+1 == hunk.startsrc:
+ hunkfind = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " -"]
+ hunkreplace = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " +"]
+ #pprint(hunkreplace)
+ hunklineno = 0
+
+ # todo \ No newline at end of file
+
+ # check hunks in source file
+ if lineno+1 < hunk.startsrc+len(hunkfind)-1:
+ if line.rstrip("\r\n") == hunkfind[hunklineno]:
+ hunklineno+=1
+ else:
+ debug("hunk no.%d doesn't match source file %s" % (hunkno+1, filename))
+ # file may be already patched, but we will check other hunks anyway
+ hunkno += 1
+ if hunkno < len(self.hunks[fileno]):
+ hunk = self.hunks[fileno][hunkno]
+ continue
+ else:
+ break
+
+ # check if processed line is the last line
+ if lineno+1 == hunk.startsrc+len(hunkfind)-1:
+ debug("file %s hunk no.%d -- is ready to be patched" % (filename, hunkno+1))
+ hunkno+=1
+ validhunks+=1
+ if hunkno < len(self.hunks[fileno]):
+ hunk = self.hunks[fileno][hunkno]
+ else:
+ if validhunks == len(self.hunks[fileno]):
+ # patch file
+ canpatch = True
+ break
+ else:
+ if hunkno < len(self.hunks[fileno]):
+ warning("premature end of source file %s at hunk %d" % (filename, hunkno+1))
+
+ f2fp.close()
+
+ if validhunks < len(self.hunks[fileno]):
+ if self._match_file_hunks(filename, self.hunks[fileno]):
+ warning("already patched %s" % filename)
+ else:
+ warning("source file is different - %s" % filename)
+ if canpatch:
+ backupname = filename+".orig"
+ if exists(backupname):
+ warning("can't backup original file to %s - aborting" % backupname)
+ else:
+ import shutil
+ shutil.move(filename, backupname)
+ if self.write_hunks(backupname, filename, self.hunks[fileno]):
+ warning("successfully patched %s" % filename)
+ unlink(backupname)
+ else:
+ warning("error patching file %s" % filename)
+ shutil.copy(filename, filename+".invalid")
+ warning("invalid version is saved to %s" % filename+".invalid")
+ # todo: proper rejects
+ shutil.move(backupname, filename)
+
+ # todo: check for premature eof
+
+
+ def can_patch(self, filename):
+ """ Check if specified filename can be patched. Returns None if file can
+ not be found among source filenames. False if patch can not be applied
+ clearly. True otherwise.
+
+ :returns: True, False or None
+ """
+ idx = self._get_file_idx(filename, source=True)
+ if idx == None:
+ return None
+ return self._match_file_hunks(filename, self.hunks[idx])
+
+
+ def _match_file_hunks(self, filepath, hunks):
+ matched = True
+ fp = open(abspath(filepath))
+
+ class NoMatch(Exception):
+ pass
+
+ lineno = 1
+ line = fp.readline()
+ hno = None
+ try:
+ for hno, h in enumerate(hunks):
+ # skip to first line of the hunk
+ while lineno < h.starttgt:
+ if not len(line): # eof
+ debug("check failed - premature eof before hunk: %d" % (hno+1))
+ raise NoMatch
+ line = fp.readline()
+ lineno += 1
+ for hline in h.text:
+ if hline.startswith("-"):
+ continue
+ if not len(line):
+ debug("check failed - premature eof on hunk: %d" % (hno+1))
+ # todo: \ No newline at the end of file
+ raise NoMatch
+ if line.rstrip("\r\n") != hline[1:].rstrip("\r\n"):
+ debug("file is not patched - failed hunk: %d" % (hno+1))
+ raise NoMatch
+ line = fp.readline()
+ lineno += 1
+
+ except NoMatch:
+ matched = False
+ # todo: display failed hunk, i.e. expected/found
+
+ fp.close()
+ return matched
+
+
+ def patch_stream(self, instream, hunks):
+ """ Generator that yields stream patched with hunks iterable
+
+ Converts lineends in hunk lines to the best suitable format
+ autodetected from input
+ """
+
+ # todo: At the moment substituted lineends may not be the same
+ # at the start and at the end of patching. Also issue a
+ # warning/throw about mixed lineends (is it really needed?)
+
+ hunks = iter(hunks)
+
+ srclineno = 1
+
+ lineends = {'\n':0, '\r\n':0, '\r':0}
+ def get_line():
+ """
+ local utility function - return line from source stream
+ collecting line end statistics on the way
+ """
+ line = instream.readline()
+ # 'U' mode works only with text files
+ if line.endswith("\r\n"):
+ lineends["\r\n"] += 1
+ elif line.endswith("\n"):
+ lineends["\n"] += 1
+ elif line.endswith("\r"):
+ lineends["\r"] += 1
+ return line
+
+ for hno, h in enumerate(hunks):
+ debug("hunk %d" % (hno+1))
+ # skip to line just before hunk starts
+ while srclineno < h.startsrc:
+ yield get_line()
+ srclineno += 1
+
+ for hline in h.text:
+ # todo: check \ No newline at the end of file
+ if hline.startswith("-") or hline.startswith("\\"):
+ get_line()
+ srclineno += 1
+ continue
+ else:
+ if not hline.startswith("+"):
+ get_line()
+ srclineno += 1
+ line2write = hline[1:]
+ # detect if line ends are consistent in source file
+ if sum([bool(lineends[x]) for x in lineends]) == 1:
+ newline = [x for x in lineends if lineends[x] != 0][0]
+ yield line2write.rstrip("\r\n")+newline
+ else: # newlines are mixed
+ yield line2write
+
+ for line in instream:
+ yield line
+
+
+ def write_hunks(self, srcname, tgtname, hunks):
+ src = open(srcname, "rb")
+ tgt = open(tgtname, "wb")
+
+ debug("processing target file %s" % tgtname)
+
+ tgt.writelines(self.patch_stream(src, hunks))
+
+ tgt.close()
+ src.close()
+ return True
+
+
+ def _get_file_idx(self, filename, source=None):
+ """ Detect index of given filename within patch.
+
+ :param filename:
+ :param source: search filename among sources (True),
+ targets (False), or both (None)
+ :returns: int or None
+ """
+ filename = abspath(filename)
+ if source == True or source == None:
+ for i,fnm in enumerate(self.source):
+ if filename == abspath(fnm):
+ return i
+ if source == False or source == None:
+ for i,fnm in enumerate(self.target):
+ if filename == abspath(fnm):
+ return i
+
+
+
+
+from optparse import OptionParser
+from os.path import exists
+import sys
+
+if __name__ == "__main__":
+ opt = OptionParser(usage="%prog [options] unipatch-file", version="python-patch %s" % __version__)
+ opt.add_option("--debug", action="store_true", dest="debugmode", help="debug mode")
+ (options, args) = opt.parse_args()
+
+ if not args:
+ opt.print_version()
+ opt.print_help()
+ sys.exit()
+ debugmode = options.debugmode
+ patchfile = args[0]
+ if not exists(patchfile) or not isfile(patchfile):
+ sys.exit("patch file does not exist - %s" % patchfile)
+
+
+ if debugmode:
+ loglevel = logging.DEBUG
+ logformat = "%(levelname)8s %(message)s"
+ else:
+ loglevel = logging.INFO
+ logformat = "%(message)s"
+ logger.setLevel(loglevel)
+ loghandler.setFormatter(logging.Formatter(logformat))
+
+
+
+ patch = fromfile(patchfile)
+ #pprint(patch)
+ patch.apply()
+
+ # todo: document and test line ends handling logic - patch.py detects proper line-endings
+ # for inserted hunks and issues a warning if patched file has incosistent line ends
Binary file virtualenv/res/src/Django-1.2.4.tar.gz has changed
Binary file virtualenv/res/src/Imaging-1.1.7.tar.gz has changed
Binary file virtualenv/res/src/JCC-2.6-py2.6-win32.egg has changed
Binary file virtualenv/res/src/MySQL-python-1.2.3.tar.gz has changed
Binary file virtualenv/res/src/PIL-1.1.7.win32-py2.6.exe has changed
Binary file virtualenv/res/src/distribute-0.6.14.tar.gz has changed
Binary file virtualenv/res/src/django-extensions-0.6.tar.gz has changed
Binary file virtualenv/res/src/django-oauth-plus.tar.gz has changed
Binary file virtualenv/res/src/django-piston-0.2.2-modified.tar.gz has changed
Binary file virtualenv/res/src/django-registration.tar.gz has changed
Binary file virtualenv/res/src/django-tagging-0.3.1.tar.gz has changed
Binary file virtualenv/res/src/httplib2-0.6.0.tar.gz has changed
Binary file virtualenv/res/src/jogging-0.2.2.tar.gz has changed
Binary file virtualenv/res/src/lucene-3.0.2-py2.6-win32.egg has changed
Binary file virtualenv/res/src/lxml-2.2.8-py2.6-win32.egg has changed
Binary file virtualenv/res/src/lxml-2.2.8.tar.gz has changed
Binary file virtualenv/res/src/mercurial-1.7.5.tar.gz has changed
Binary file virtualenv/res/src/psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip has changed
Binary file virtualenv/res/src/psycopg2-2.3.2.tar.gz has changed
Binary file virtualenv/res/src/pylucene-3.0.3-1-src.tar.gz has changed
Binary file virtualenv/res/src/python-oauth2-1.2.1-modified.tar.gz has changed
Binary file virtualenv/res/src/setuptools_hg-0.2.tar.gz has changed
--- a/virtualenv/setup/create_python_env.py Fri Mar 25 21:39:53 2011 +0100
+++ b/virtualenv/setup/create_python_env.py Tue Mar 29 13:33:43 2011 +0200
@@ -29,15 +29,16 @@
# - 4Suite-xml - easy_install ftp://ftp.4suite.org/pub/4Suite/4Suite-XML-1.0.2.tar.bz2
# - pylucene - script
-src_base = os.path.join(here,"res","src").replace("\\","/")
-lib_path = os.path.abspath(os.path.join(here,"res","lib")).replace("\\","/")
+src_base = os.path.abspath(os.path.join(here,"..","res","src")).replace("\\","/")
+lib_path = os.path.abspath(os.path.join(here,"..","res","lib")).replace("\\","/")
+patch_path = os.path.abspath(os.path.join(here,"res","patch")).replace("\\","/")
+
EXTRA_TEXT = "import sys\n"
EXTRA_TEXT += "sys.path.append('%s')\n" % (lib_path)
-f = open(os.path.join(os.path. os.path.join(os.path.dirname(os.path.abspath(__file__)),"res"),'res_create_env.py'), 'r')
-EXTRA_TEXT += f.read()
-EXTRA_TEXT += "\n"
-EXTRA_TEXT += "RES_ENV = ResourcesEnv('%s')\n" % (src_base)
+EXTRA_TEXT += "sys.path.append('%s')\n" % (os.path.abspath(os.path.join(here,"res")).replace("\\","/"))
+EXTRA_TEXT += "from res_create_env import generate_install_methods\n"
+EXTRA_TEXT += "adjust_options, extend_parser, after_install = generate_install_methods(path_locations, '%s', Logger, call_subprocess)\n" % (src_base)
def main():
--- a/virtualenv/setup/res/res_create_env.py Fri Mar 25 21:39:53 2011 +0100
+++ b/virtualenv/setup/res/res_create_env.py Tue Mar 29 13:33:43 2011 +0200
@@ -1,249 +1,15 @@
-import sys
-import os
-import os.path
-import shutil
-import tarfile
-import zipfile
-import urllib
import platform
-import patch
-import logging
-
-class ResourcesEnv(object):
-
- def __init__(self, src_base):
- self.src_base = src_base
- self.URLS = {}
- self.__init_url()
- self.NORMAL_INSTALL = []
- self.__init_normal_install()
-
- def get_src_base_path(self, fpath):
- return os.path.abspath(os.path.join(self.src_base, fpath)).replace("\\","/")
-
- def __add_package_def(self, key, setup, url, local):
- self.URLS[key] = {'setup':setup, 'url':url, 'local':self.get_src_base_path(local)}
-
- def __init_url(self):
- self.__add_package_def('DISTRIBUTE', setup='distribute', url='http://pypi.python.org/packages/source/d/distribute/distribute-0.6.14.tar.gz', local="distribute-0.6.14.tar.gz")
- self.__add_package_def('MERCURIAL', setup='mercurial', url='http://pypi.python.org/packages/source/d/mercurial/mercurial-1.7.5.tar.gz', local="mercurial-1.7.5.tar.gz")
- self.__add_package_def('SETUPTOOLS-HG', setup='mercurial_hg', url='http://pypi.python.org/packages/source/s/setuptools_hg/setuptools_hg-0.2.tar.gz', local="setuptools_hg-0.2.tar.gz")
-
- def __init_normal_install(self):
- system_str = platform.system()
- self.NORMAL_INSTALL = [ #(key,method, option_str, extra_env)
- ('DISTRIBUTE', 'pip', None, None),
- ('MERCURIAL', 'pip', None, None),
- ('SETUPTOOLS-HG', 'pip', None, None),
- ]
+from lib_create_env import lib_generate_install_methods, install_pylucene, install_psycopg2
-def extend_parser(parser):
-
- parser.add_option(
- '--index-url',
- metavar='INDEX_URL',
- dest='index_url',
- default='http://pypi.python.org/simple/',
- help='base URL of Python Package Index')
- parser.add_option(
- '--type-install',
- metavar='type_install',
- dest='type_install',
- default='local',
- help='type install : local, url, setup')
- parser.add_option(
- '--ignore-packages',
- metavar='ignore_packages',
- dest='ignore_packages',
- default=None,
- help='list of comma separated keys for package to ignore')
-
-
-def adjust_options(options, args):
- pass
+system_str = platform.system()
-def after_install(options, home_dir):
- global RES_ENV
- #global path_locations
- home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
- base_dir = os.path.dirname(home_dir)
- src_dir = os.path.join(home_dir, 'src')
- tmp_dir = os.path.join(home_dir, 'tmp')
- ensure_dir(src_dir)
- ensure_dir(tmp_dir)
- system_str = platform.system()
-
- res_source_key = options.type_install
-
- ignore_packages = []
-
- if options.ignore_packages :
- ignore_packages = options.ignore_packages.split(",")
-
- logger.indent += 2
- try:
-
- if 'PYLUCENE' not in ignore_packages and system_str != "Windows":
- #get pylucene
- logger.notify("Get Pylucene from %s " % RES_ENV.URLS['PYLUCENE'][res_source_key])
- pylucene_src = os.path.join(src_dir,"pylucene.tar.gz")
- if res_source_key == 'local':
- shutil.copy(RES_ENV.URLS['PYLUCENE'][res_source_key], pylucene_src)
- else:
- urllib.urlretrieve(RES_ENV.URLS['PYLUCENE'][res_source_key], pylucene_src)
- tf = tarfile.open(pylucene_src,'r:gz')
- pylucene_base_path = os.path.join(src_dir,"pylucene")
- logger.notify("Extract Pylucene to %s " % pylucene_base_path)
- tf.extractall(pylucene_base_path)
- tf.close()
-
- pylucene_src_path = os.path.join(pylucene_base_path, os.listdir(pylucene_base_path)[0])
- jcc_src_path = os.path.abspath(os.path.join(pylucene_src_path,"jcc"))
-
- #install jcc
-
- #patch for linux
- if system_str == 'Linux' :
- olddir = os.getcwd()
- patch_dest_path = os.path.join(lib_dir,'site-packages','setuptools-0.6c11-py'+'%s.%s' % (sys.version_info[0], sys.version_info[1])+'.egg')
- if os.path.isfile(patch_dest_path):
- # must unzip egg
- # rename file and etract all
- shutil.move(patch_dest_path, patch_dest_path + ".zip")
- zf = zipfile.ZipFile(patch_dest_path + ".zip",'r')
- zf.extractall(patch_dest_path)
- os.remove(patch_dest_path + ".zip")
- logger.notify("Patch jcc : %s " % (patch_dest_path))
- os.chdir(patch_dest_path)
- p = patch.fromfile(os.path.join(jcc_src_path,"jcc","patches","patch.43.0.6c11"))
- p.apply()
- os.chdir(olddir)
-
- logger.notify("Install jcc")
- call_subprocess([os.path.abspath(os.path.join(home_dir, 'bin', 'python')), 'setup.py', 'install'],
- cwd=jcc_src_path,
- filter_stdout=filter_python_develop,
- show_stdout=True)
- #install pylucene
-
- logger.notify("Install pylucene")
- #modify makefile
- makefile_path = os.path.join(pylucene_src_path,"Makefile")
- logger.notify("Modify makefile %s " % makefile_path)
- shutil.move( makefile_path, makefile_path+"~" )
-
- destination= open( makefile_path, "w" )
- source= open( makefile_path+"~", "r" )
- destination.write("PREFIX_PYTHON="+os.path.abspath(home_dir)+"\\n")
- destination.write("ANT=ant\\n")
- destination.write("PYTHON=$(PREFIX_PYTHON)/bin/python\\n")
-
- if system_str == "Darwin":
- if sys.version_info >= (2,6):
- destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\\n")
- else:
- destination.write("JCC=$(PYTHON) -m jcc --shared --arch x86_64 --arch i386\\n")
- destination.write("NUM_FILES=2\\n")
- elif system_str == "Windows":
- destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\\n")
- destination.write("NUM_FILES=2\\n")
- else:
- if sys.version_info >= (2,6) and sys.version_info <= (2,7):
- destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared\\n")
- else:
- destination.write("JCC=$(PYTHON) -m jcc --shared\\n")
- destination.write("NUM_FILES=2\\n")
- for line in source:
- destination.write( line )
- source.close()
- destination.close()
- os.remove(makefile_path+"~" )
-
- logger.notify("pylucene make")
- call_subprocess(['make'],
- cwd=os.path.abspath(pylucene_src_path),
- filter_stdout=filter_python_develop,
- show_stdout=True)
-
- logger.notify("pylucene make install")
- call_subprocess(['make', 'install'],
- cwd=os.path.abspath(pylucene_src_path),
- filter_stdout=filter_python_develop,
- show_stdout=True)
+INSTALLS = [#(key,method, option_str, dict_extra_env)
+ ('DISTRIBUTE', 'pip', None, None),
+ ('MERCURIAL', 'pip', None, None),
+ ('SETUPTOOLS-HG', 'pip', None, None),
+]
-
- if 'PSYCOPG2' not in ignore_packages and system_str == "Windows":
- #get psycopg2
- psycopg2_src = os.path.join(src_dir,"psycopg2.zip")
- shutil.copy(RES_ENV.URLS['PSYCOPG2'][res_source_key], psycopg2_src)
- #extract psycopg2
- zf = zipfile.ZipFile(psycopg2_src)
- psycopg2_base_path = os.path.join(src_dir,"psycopg2")
- zf.extractall(psycopg2_base_path)
- zf.close()
-
- psycopg2_src_path = os.path.join(psycopg2_base_path, os.listdir(psycopg2_base_path)[0])
- shutil.copytree(os.path.join(psycopg2_src_path, 'psycopg2'), os.path.abspath(os.path.join(home_dir, 'Lib', 'psycopg2')))
- shutil.copy(os.path.join(psycopg2_src_path, 'psycopg2-2.0.10-py2.6.egg-info'), os.path.abspath(os.path.join(home_dir, 'Lib', 'site-packages')))
-
- for key, method, option_str, extra_env in RES_ENV.NORMAL_INSTALL:
- if key not in ignore_packages:
- normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir)
-
- logger.notify("Clear source dir")
- shutil.rmtree(src_dir)
-
- finally:
- logger.indent -= 2
- script_dir = join(base_dir, bin_dir)
- logger.notify('Run "%s Package" to install new packages that provide builds'
- % join(script_dir, 'easy_install'))
-
-
-def normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir):
- global logger
- logger.notify("Install %s from %s with %s" % (key,RES_ENV.URLS[key][res_source_key],method))
- if method == 'pip':
- if sys.platform == 'win32':
- args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'pip')), 'install', '-E', os.path.abspath(home_dir), RES_ENV.URLS[key][res_source_key]]
- else:
- args = [os.path.abspath(os.path.join(home_dir, 'bin', 'pip')), 'install', '-E', os.path.abspath(home_dir), RES_ENV.URLS[key][res_source_key]]
- if option_str :
- args.insert(4,option_str)
- call_subprocess(args,
- cwd=os.path.abspath(tmp_dir),
- filter_stdout=filter_python_develop,
- show_stdout=True,
- extra_env=extra_env)
- else:
- if sys.platform == 'win32':
- args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'easy_install')), RES_ENV.URLS[key][res_source_key]]
- else:
- args = [os.path.abspath(os.path.join(home_dir, 'bin', 'easy_install')), RES_ENV.URLS[key][res_source_key]]
- if option_str :
- args.insert(1,option_str)
- call_subprocess(args,
- cwd=os.path.abspath(tmp_dir),
- filter_stdout=filter_python_develop,
- show_stdout=True,
- extra_env=extra_env)
-
-
-def ensure_dir(dir):
- global logger
- if not os.path.exists(dir):
- logger.notify('Creating directory %s' % dir)
- os.makedirs(dir)
-
-def filter_python_develop(line):
- global logger
- if not line.strip():
- return Logger.DEBUG
- for prefix in ['Searching for', 'Reading ', 'Best match: ', 'Processing ',
- 'Moving ', 'Adding ', 'running ', 'writing ', 'Creating ',
- 'creating ', 'Copying ']:
- if line.startswith(prefix):
- return Logger.DEBUG
- return Logger.NOTIFY
+def generate_install_methods(path_locations, src_base, Logger, call_subprocess):
+ return lib_generate_install_methods(path_locations, src_base, Logger, call_subprocess, INSTALLS)
Binary file virtualenv/setup/res/src/distribute-0.6.14.tar.gz has changed
Binary file virtualenv/setup/res/src/mercurial-1.7.5.tar.gz has changed
Binary file virtualenv/setup/res/src/setuptools_hg-0.2.tar.gz has changed
--- a/virtualenv/web/create_python_env.py Fri Mar 25 21:39:53 2011 +0100
+++ b/virtualenv/web/create_python_env.py Tue Mar 29 13:33:43 2011 +0200
@@ -34,8 +34,8 @@
# - 4Suite-xml - easy_install ftp://ftp.4suite.org/pub/4Suite/4Suite-XML-1.0.2.tar.bz2
# - pylucene - script
-src_base = os.path.join(here,"res","src").replace("\\","/")
-lib_path = os.path.abspath(os.path.join(here,"res","lib")).replace("\\","/")
+src_base = os.path.abspath(os.path.join(here,"..","res","src")).replace("\\","/")
+lib_path = os.path.abspath(os.path.join(here,"..","res","lib")).replace("\\","/")
patch_path = os.path.abspath(os.path.join(here,"res","patch")).replace("\\","/")
--- a/virtualenv/web/res/lib/patch.py Fri Mar 25 21:39:53 2011 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,589 +0,0 @@
-""" Patch utility to apply unified diffs
-
- Brute-force line-by-line non-recursive parsing
-
- Copyright (c) 2008-2010 anatoly techtonik
- Available under the terms of MIT license
-
- Project home: http://code.google.com/p/python-patch/
-
-
- $Id: patch.py 76 2010-04-08 19:10:21Z techtonik $
- $HeadURL: https://python-patch.googlecode.com/svn/trunk/patch.py $
-"""
-
-__author__ = "techtonik.rainforce.org"
-__version__ = "10.04"
-
-import copy
-import logging
-import re
-# cStringIO doesn't support unicode in 2.5
-from StringIO import StringIO
-from logging import debug, info, warning
-
-from os.path import exists, isfile, abspath
-from os import unlink
-
-
-#------------------------------------------------
-# Logging is controlled by "python_patch" logger
-
-debugmode = False
-
-logger = logging.getLogger("python_patch")
-loghandler = logging.StreamHandler()
-logger.addHandler(loghandler)
-
-debug = logger.debug
-info = logger.info
-warning = logger.warning
-
-#: disable library logging by default
-logger.setLevel(logging.CRITICAL)
-
-#------------------------------------------------
-
-
-def fromfile(filename):
- """ Parse patch file and return Patch() object
- """
-
- info("reading patch from file %s" % filename)
- fp = open(filename, "rb")
- patch = Patch(fp)
- fp.close()
- return patch
-
-
-def fromstring(s):
- """ Parse text string and return Patch() object
- """
-
- return Patch(
- StringIO.StringIO(s)
- )
-
-
-
-class HunkInfo(object):
- """ Parsed hunk data container (hunk starts with @@ -R +R @@) """
-
- def __init__(self):
- self.startsrc=None #: line count starts with 1
- self.linessrc=None
- self.starttgt=None
- self.linestgt=None
- self.invalid=False
- self.text=[]
-
- def copy(self):
- return copy.copy(self)
-
-# def apply(self, estream):
-# """ write hunk data into enumerable stream
-# return strings one by one until hunk is
-# over
-#
-# enumerable stream are tuples (lineno, line)
-# where lineno starts with 0
-# """
-# pass
-
-
-
-class Patch(object):
-
- def __init__(self, stream=None):
-
- # define Patch data members
- # table with a row for every source file
-
- #: list of source filenames
- self.source=None
- self.target=None
- #: list of lists of hunks
- self.hunks=None
- #: file endings statistics for every hunk
- self.hunkends=None
-
- if stream:
- self.parse(stream)
-
- def copy(self):
- return copy.copy(self)
-
- def parse(self, stream):
- """ parse unified diff """
- self.source = []
- self.target = []
- self.hunks = []
- self.hunkends = []
-
- # define possible file regions that will direct the parser flow
- header = False # comments before the patch body
- filenames = False # lines starting with --- and +++
-
- hunkhead = False # @@ -R +R @@ sequence
- hunkbody = False #
- hunkskip = False # skipping invalid hunk mode
-
- header = True
- lineends = dict(lf=0, crlf=0, cr=0)
- nextfileno = 0
- nexthunkno = 0 #: even if index starts with 0 user messages number hunks from 1
-
- # hunkinfo holds parsed values, hunkactual - calculated
- hunkinfo = HunkInfo()
- hunkactual = dict(linessrc=None, linestgt=None)
-
- fe = enumerate(stream)
- for lineno, line in fe:
-
- # analyze state
- if header and line.startswith("--- "):
- header = False
- # switch to filenames state
- filenames = True
- #: skip hunkskip and hunkbody code until you read definition of hunkhead
- if hunkbody:
- # process line first
- if re.match(r"^[- \+\\]", line):
- # gather stats about line endings
- if line.endswith("\r\n"):
- self.hunkends[nextfileno-1]["crlf"] += 1
- elif line.endswith("\n"):
- self.hunkends[nextfileno-1]["lf"] += 1
- elif line.endswith("\r"):
- self.hunkends[nextfileno-1]["cr"] += 1
-
- if line.startswith("-"):
- hunkactual["linessrc"] += 1
- elif line.startswith("+"):
- hunkactual["linestgt"] += 1
- elif not line.startswith("\\"):
- hunkactual["linessrc"] += 1
- hunkactual["linestgt"] += 1
- hunkinfo.text.append(line)
- # todo: handle \ No newline cases
- else:
- warning("invalid hunk no.%d at %d for target file %s" % (nexthunkno, lineno+1, self.target[nextfileno-1]))
- # add hunk status node
- self.hunks[nextfileno-1].append(hunkinfo.copy())
- self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True
- # switch to hunkskip state
- hunkbody = False
- hunkskip = True
-
- # check exit conditions
- if hunkactual["linessrc"] > hunkinfo.linessrc or hunkactual["linestgt"] > hunkinfo.linestgt:
- warning("extra hunk no.%d lines at %d for target %s" % (nexthunkno, lineno+1, self.target[nextfileno-1]))
- # add hunk status node
- self.hunks[nextfileno-1].append(hunkinfo.copy())
- self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True
- # switch to hunkskip state
- hunkbody = False
- hunkskip = True
- elif hunkinfo.linessrc == hunkactual["linessrc"] and hunkinfo.linestgt == hunkactual["linestgt"]:
- self.hunks[nextfileno-1].append(hunkinfo.copy())
- # switch to hunkskip state
- hunkbody = False
- hunkskip = True
-
- # detect mixed window/unix line ends
- ends = self.hunkends[nextfileno-1]
- if ((ends["cr"]!=0) + (ends["crlf"]!=0) + (ends["lf"]!=0)) > 1:
- warning("inconsistent line ends in patch hunks for %s" % self.source[nextfileno-1])
- if debugmode:
- debuglines = dict(ends)
- debuglines.update(file=self.target[nextfileno-1], hunk=nexthunkno)
- debug("crlf: %(crlf)d lf: %(lf)d cr: %(cr)d\t - file: %(file)s hunk: %(hunk)d" % debuglines)
-
- if hunkskip:
- match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line)
- if match:
- # switch to hunkhead state
- hunkskip = False
- hunkhead = True
- elif line.startswith("--- "):
- # switch to filenames state
- hunkskip = False
- filenames = True
- if debugmode and len(self.source) > 0:
- debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1]))
-
- if filenames:
- if line.startswith("--- "):
- if nextfileno in self.source:
- warning("skipping invalid patch for %s" % self.source[nextfileno])
- del self.source[nextfileno]
- # double source filename line is encountered
- # attempt to restart from this second line
- re_filename = "^--- ([^\t]+)"
- match = re.match(re_filename, line)
- # todo: support spaces in filenames
- if match:
- self.source.append(match.group(1).strip())
- else:
- warning("skipping invalid filename at line %d" % lineno)
- # switch back to header state
- filenames = False
- header = True
- elif not line.startswith("+++ "):
- if nextfileno in self.source:
- warning("skipping invalid patch with no target for %s" % self.source[nextfileno])
- del self.source[nextfileno]
- else:
- # this should be unreachable
- warning("skipping invalid target patch")
- filenames = False
- header = True
- else:
- if nextfileno in self.target:
- warning("skipping invalid patch - double target at line %d" % lineno)
- del self.source[nextfileno]
- del self.target[nextfileno]
- nextfileno -= 1
- # double target filename line is encountered
- # switch back to header state
- filenames = False
- header = True
- else:
- re_filename = "^\+\+\+ ([^\t]+)"
- match = re.match(re_filename, line)
- if not match:
- warning("skipping invalid patch - no target filename at line %d" % lineno)
- # switch back to header state
- filenames = False
- header = True
- else:
- self.target.append(match.group(1).strip())
- nextfileno += 1
- # switch to hunkhead state
- filenames = False
- hunkhead = True
- nexthunkno = 0
- self.hunks.append([])
- self.hunkends.append(lineends.copy())
- continue
-
- if hunkhead:
- match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line)
- if not match:
- if nextfileno-1 not in self.hunks:
- warning("skipping invalid patch with no hunks for file %s" % self.target[nextfileno-1])
- # switch to header state
- hunkhead = False
- header = True
- continue
- else:
- # switch to header state
- hunkhead = False
- header = True
- else:
- hunkinfo.startsrc = int(match.group(1))
- hunkinfo.linessrc = 1
- if match.group(3): hunkinfo.linessrc = int(match.group(3))
- hunkinfo.starttgt = int(match.group(4))
- hunkinfo.linestgt = 1
- if match.group(6): hunkinfo.linestgt = int(match.group(6))
- hunkinfo.invalid = False
- hunkinfo.text = []
-
- hunkactual["linessrc"] = hunkactual["linestgt"] = 0
-
- # switch to hunkbody state
- hunkhead = False
- hunkbody = True
- nexthunkno += 1
- continue
- else:
- if not hunkskip:
- warning("patch file incomplete - %s" % filename)
- # sys.exit(?)
- else:
- # duplicated message when an eof is reached
- if debugmode and len(self.source) > 0:
- debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1]))
-
- info("total files: %d total hunks: %d" % (len(self.source), sum(len(hset) for hset in self.hunks)))
-
-
- def apply(self):
- """ apply parsed patch """
-
- total = len(self.source)
- for fileno, filename in enumerate(self.source):
-
- f2patch = filename
- if not exists(f2patch):
- f2patch = self.target[fileno]
- if not exists(f2patch):
- warning("source/target file does not exist\n--- %s\n+++ %s" % (filename, f2patch))
- continue
- if not isfile(f2patch):
- warning("not a file - %s" % f2patch)
- continue
- filename = f2patch
-
- info("processing %d/%d:\t %s" % (fileno+1, total, filename))
-
- # validate before patching
- f2fp = open(filename)
- hunkno = 0
- hunk = self.hunks[fileno][hunkno]
- hunkfind = []
- hunkreplace = []
- validhunks = 0
- canpatch = False
- for lineno, line in enumerate(f2fp):
- if lineno+1 < hunk.startsrc:
- continue
- elif lineno+1 == hunk.startsrc:
- hunkfind = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " -"]
- hunkreplace = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " +"]
- #pprint(hunkreplace)
- hunklineno = 0
-
- # todo \ No newline at end of file
-
- # check hunks in source file
- if lineno+1 < hunk.startsrc+len(hunkfind)-1:
- if line.rstrip("\r\n") == hunkfind[hunklineno]:
- hunklineno+=1
- else:
- debug("hunk no.%d doesn't match source file %s" % (hunkno+1, filename))
- # file may be already patched, but we will check other hunks anyway
- hunkno += 1
- if hunkno < len(self.hunks[fileno]):
- hunk = self.hunks[fileno][hunkno]
- continue
- else:
- break
-
- # check if processed line is the last line
- if lineno+1 == hunk.startsrc+len(hunkfind)-1:
- debug("file %s hunk no.%d -- is ready to be patched" % (filename, hunkno+1))
- hunkno+=1
- validhunks+=1
- if hunkno < len(self.hunks[fileno]):
- hunk = self.hunks[fileno][hunkno]
- else:
- if validhunks == len(self.hunks[fileno]):
- # patch file
- canpatch = True
- break
- else:
- if hunkno < len(self.hunks[fileno]):
- warning("premature end of source file %s at hunk %d" % (filename, hunkno+1))
-
- f2fp.close()
-
- if validhunks < len(self.hunks[fileno]):
- if self._match_file_hunks(filename, self.hunks[fileno]):
- warning("already patched %s" % filename)
- else:
- warning("source file is different - %s" % filename)
- if canpatch:
- backupname = filename+".orig"
- if exists(backupname):
- warning("can't backup original file to %s - aborting" % backupname)
- else:
- import shutil
- shutil.move(filename, backupname)
- if self.write_hunks(backupname, filename, self.hunks[fileno]):
- warning("successfully patched %s" % filename)
- unlink(backupname)
- else:
- warning("error patching file %s" % filename)
- shutil.copy(filename, filename+".invalid")
- warning("invalid version is saved to %s" % filename+".invalid")
- # todo: proper rejects
- shutil.move(backupname, filename)
-
- # todo: check for premature eof
-
-
- def can_patch(self, filename):
- """ Check if specified filename can be patched. Returns None if file can
- not be found among source filenames. False if patch can not be applied
- clearly. True otherwise.
-
- :returns: True, False or None
- """
- idx = self._get_file_idx(filename, source=True)
- if idx == None:
- return None
- return self._match_file_hunks(filename, self.hunks[idx])
-
-
- def _match_file_hunks(self, filepath, hunks):
- matched = True
- fp = open(abspath(filepath))
-
- class NoMatch(Exception):
- pass
-
- lineno = 1
- line = fp.readline()
- hno = None
- try:
- for hno, h in enumerate(hunks):
- # skip to first line of the hunk
- while lineno < h.starttgt:
- if not len(line): # eof
- debug("check failed - premature eof before hunk: %d" % (hno+1))
- raise NoMatch
- line = fp.readline()
- lineno += 1
- for hline in h.text:
- if hline.startswith("-"):
- continue
- if not len(line):
- debug("check failed - premature eof on hunk: %d" % (hno+1))
- # todo: \ No newline at the end of file
- raise NoMatch
- if line.rstrip("\r\n") != hline[1:].rstrip("\r\n"):
- debug("file is not patched - failed hunk: %d" % (hno+1))
- raise NoMatch
- line = fp.readline()
- lineno += 1
-
- except NoMatch:
- matched = False
- # todo: display failed hunk, i.e. expected/found
-
- fp.close()
- return matched
-
-
- def patch_stream(self, instream, hunks):
- """ Generator that yields stream patched with hunks iterable
-
- Converts lineends in hunk lines to the best suitable format
- autodetected from input
- """
-
- # todo: At the moment substituted lineends may not be the same
- # at the start and at the end of patching. Also issue a
- # warning/throw about mixed lineends (is it really needed?)
-
- hunks = iter(hunks)
-
- srclineno = 1
-
- lineends = {'\n':0, '\r\n':0, '\r':0}
- def get_line():
- """
- local utility function - return line from source stream
- collecting line end statistics on the way
- """
- line = instream.readline()
- # 'U' mode works only with text files
- if line.endswith("\r\n"):
- lineends["\r\n"] += 1
- elif line.endswith("\n"):
- lineends["\n"] += 1
- elif line.endswith("\r"):
- lineends["\r"] += 1
- return line
-
- for hno, h in enumerate(hunks):
- debug("hunk %d" % (hno+1))
- # skip to line just before hunk starts
- while srclineno < h.startsrc:
- yield get_line()
- srclineno += 1
-
- for hline in h.text:
- # todo: check \ No newline at the end of file
- if hline.startswith("-") or hline.startswith("\\"):
- get_line()
- srclineno += 1
- continue
- else:
- if not hline.startswith("+"):
- get_line()
- srclineno += 1
- line2write = hline[1:]
- # detect if line ends are consistent in source file
- if sum([bool(lineends[x]) for x in lineends]) == 1:
- newline = [x for x in lineends if lineends[x] != 0][0]
- yield line2write.rstrip("\r\n")+newline
- else: # newlines are mixed
- yield line2write
-
- for line in instream:
- yield line
-
-
- def write_hunks(self, srcname, tgtname, hunks):
- src = open(srcname, "rb")
- tgt = open(tgtname, "wb")
-
- debug("processing target file %s" % tgtname)
-
- tgt.writelines(self.patch_stream(src, hunks))
-
- tgt.close()
- src.close()
- return True
-
-
- def _get_file_idx(self, filename, source=None):
- """ Detect index of given filename within patch.
-
- :param filename:
- :param source: search filename among sources (True),
- targets (False), or both (None)
- :returns: int or None
- """
- filename = abspath(filename)
- if source == True or source == None:
- for i,fnm in enumerate(self.source):
- if filename == abspath(fnm):
- return i
- if source == False or source == None:
- for i,fnm in enumerate(self.target):
- if filename == abspath(fnm):
- return i
-
-
-
-
-from optparse import OptionParser
-from os.path import exists
-import sys
-
-if __name__ == "__main__":
- opt = OptionParser(usage="%prog [options] unipatch-file", version="python-patch %s" % __version__)
- opt.add_option("--debug", action="store_true", dest="debugmode", help="debug mode")
- (options, args) = opt.parse_args()
-
- if not args:
- opt.print_version()
- opt.print_help()
- sys.exit()
- debugmode = options.debugmode
- patchfile = args[0]
- if not exists(patchfile) or not isfile(patchfile):
- sys.exit("patch file does not exist - %s" % patchfile)
-
-
- if debugmode:
- loglevel = logging.DEBUG
- logformat = "%(levelname)8s %(message)s"
- else:
- loglevel = logging.INFO
- logformat = "%(message)s"
- logger.setLevel(loglevel)
- loghandler.setFormatter(logging.Formatter(logformat))
-
-
-
- patch = fromfile(patchfile)
- #pprint(patch)
- patch.apply()
-
- # todo: document and test line ends handling logic - patch.py detects proper line-endings
- # for inserted hunks and issues a warning if patched file has incosistent line ends
--- a/virtualenv/web/res/res_create_env.py Fri Mar 25 21:39:53 2011 +0100
+++ b/virtualenv/web/res/res_create_env.py Tue Mar 29 13:33:43 2011 +0200
@@ -1,303 +1,54 @@
-import sys
-import os
-import os.path
-import shutil
-import tarfile
-import zipfile
-import urllib
import platform
-import patch
-
-join = os.path.join
-
-class ResourcesEnv(object):
-
- def __init__(self, src_base):
- self.src_base = src_base
- self.URLS = {}
- self.__init_url()
- self.NORMAL_INSTALL = []
- self.__init_normal_install()
-
- def get_src_base_path(self, fpath):
- return os.path.abspath(os.path.join(self.src_base, fpath)).replace("\\","/")
-
- def __add_package_def(self, key, setup, url, local):
- self.URLS[key] = {'setup':setup, 'url':url, 'local':self.get_src_base_path(local)}
-
- def __init_url(self):
- self.__add_package_def('DISTRIBUTE', setup='distribute', url='http://pypi.python.org/packages/source/d/distribute/distribute-0.6.14.tar.gz', local="distribute-0.6.14.tar.gz")
- self.__add_package_def('DJANGO', setup= 'django', url= 'http://www.djangoproject.com/download/1.2.4/tarball/', local="Django-1.2.4.tar.gz")
- self.__add_package_def('JOGGING', setup= 'jogging', url= 'http://github.com/zain/jogging/tarball/v0.2.2', local="jogging-0.2.2.tar.gz")
- self.__add_package_def('DJANGO-EXTENSIONS', setup= 'django-extensions', url='https://github.com/django-extensions/django-extensions/tarball/0.6', local="django-extensions-0.6.tar.gz")
- self.__add_package_def('DJANGO-REGISTRATION', setup= 'django-registration', url='http://bitbucket.org/ubernostrum/django-registration/get/tip.tar.gz', local="django-registration.tar.gz")
- self.__add_package_def('DJANGO-TAGGING', setup= 'django-tagging', url='http://django-tagging.googlecode.com/files/django-tagging-0.3.1.tar.gz', local="django-tagging-0.3.1.tar.gz")
- self.__add_package_def('DJANGO-PISTON', setup= 'django-piston', url=self.get_src_base_path("django-piston-0.2.2-modified.tar.gz"), local="django-piston-0.2.2-modified.tar.gz")
- self.__add_package_def('OAUTH2', setup= 'python-oauth2', url=self.get_src_base_path("python-oauth2-1.2.1-modified.tar.gz"), local="python-oauth2-1.2.1-modified.tar.gz")
- self.__add_package_def('HTTPLIB2', setup= 'python-oauth2', url='http://httplib2.googlecode.com/files/httplib2-0.6.0.tar.gz', local="httplib2-0.6.0.tar.gz")
- self.__add_package_def('DJANGO-OAUTH-PLUS', setup= 'django-oauth-plus', url='http://bitbucket.org/david/django-oauth-plus/get/f314f018e473.gz', local="django-oauth-plus.tar.gz")
- self.__add_package_def('MYSQL', setup= 'mysql-python', url= 'http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.3/MySQL-python-1.2.3.tar.gz/download', local="MySQL-python-1.2.3.tar.gz")
- self.__add_package_def('SETUPTOOLS-HG', setup='mercurial_hg', url='http://pypi.python.org/packages/source/s/setuptools_hg/setuptools_hg-0.2.tar.gz', local="setuptools_hg-0.2.tar.gz")
- if sys.platform == 'win32':
- self.__add_package_def('PSYCOPG2', setup= 'psycopg2',url= self.get_src_base_path('psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip'), local="psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip")
- self.__add_package_def('JCC', setup= 'http://pylucene-win32-binary.googlecode.com/files/JCC-2.6-py2.6-win32.egg', local="JCC-2.6-py2.6-win32.egg")
- self.__add_package_def('PYLUCENE', setup= 'http://pylucene-win32-binary.googlecode.com/files/lucene-3.0.2-py2.6-win32.egg', local="lucene-3.0.2-py2.6-win32.egg")
- self.__add_package_def('PIL', setup= 'pil', url= 'http://effbot.org/media/downloads/PIL-1.1.7.win32-py2.6.exe', local="PIL-1.1.7.win32-py2.6.exe")
- self.__add_package_def('LXML', setup= 'lxml', url= 'http://pypi.python.org/packages/2.6/l/lxml/lxml-2.2.8-py2.6-win32.egg', local="lxml-2.2.8-py2.6-win32.egg")
- else:
- self.__add_package_def('PSYCOPG2', setup= 'psycopg2',url= 'http://initd.org/psycopg/tarballs/PSYCOPG-2-3/psycopg2-2.3.2.tar.gz', local="psycopg2-2.3.2.tar.gz")
- self.__add_package_def('PYLUCENE', setup= 'http://apache.crihan.fr/dist/lucene/pylucene/pylucene-3.0.3-1-src.tar.gz', url= 'http://apache.crihan.fr/dist/lucene/pylucene/pylucene-3.0.3-1-src.tar.gz', local="pylucene-3.0.3-1-src.tar.gz")
- self.__add_package_def('PIL', setup= 'pil', url= 'http://effbot.org/downloads/Imaging-1.1.7.tar.gz', local="Imaging-1.1.7.tar.gz")
- self.__add_package_def('LXML', setup= 'lxml', url=self.get_src_base_path("lxml_2.2.8.tar.gz"), local="lxml-2.2.8.tar.gz")
+from lib_create_env import lib_generate_install_methods, install_pylucene, install_psycopg2
- def __init_normal_install(self):
- system_str = platform.system()
- self.NORMAL_INSTALL = [ #(key,method, option_str, extra_env)
- ('SETUPTOOLS-HG', 'pip', None, None),
- ('MYSQL', 'pip', None, None),
- ('PIL', 'easy_install', None, None),
- ('DJANGO','pip', None, None),
- ('JOGGING','pip', None, None),
- ('DJANGO-EXTENSIONS', 'pip', None, None),
- ('DJANGO-REGISTRATION', 'easy_install', '-Z', None),
- ('DJANGO-TAGGING', 'pip', None, None),
- ('DJANGO-PISTON', 'pip', None, None),
- ('HTTPLIB2', 'pip', None, None),
- ('OAUTH2', 'easy_install', None, None),
- ('DJANGO-OAUTH-PLUS', 'pip', None, None),
- ]
- if system_str == "Windows":
- self.NORMAL_INSTALL.append(('JCC','easy_install',None,None))
- self.NORMAL_INSTALL.append(('PYLUCENE','easy_install',None,None))
-
- if system_str == "Darwin":
- self.NORMAL_INSTALL.append(('LXML', 'pip', None, {'STATIC_DEPS': 'true', 'LIBXML2_VERSION': '2.7.8', 'LIBXSLT_VERSION': '1.1.26'}))
- else:
- self.NORMAL_INSTALL.append(('LXML', 'pip', None, None))
-
- if system_str != "Windows":
- self.NORMAL_INSTALL.append(('PSYCOPG2', 'pip', None, None))
-
- if system_str == 'Linux':
- self.NORMAL_INSTALL.insert(0, ('DISTRIBUTE', 'pip', None, None))
+system_str = platform.system()
-def generate_install_methods(path_locations, src_base, Logger, call_subprocess):
+if system_str == 'Linux':
+ INSTALLS = [
+ ('DISTRIBUTE', 'pip', None, None),
+ ]
+else:
+ INSTALLS = []
- res_env = ResourcesEnv(src_base)
- def extend_parser(parser):
- parser.add_option(
- '--index-url',
- metavar='INDEX_URL',
- dest='index_url',
- default='http://pypi.python.org/simple/',
- help='base URL of Python Package Index')
- parser.add_option(
- '--type-install',
- metavar='type_install',
- dest='type_install',
- default='local',
- help='type install : local, url, setup')
- parser.add_option(
- '--ignore-packages',
- metavar='ignore_packages',
- dest='ignore_packages',
- default=None,
- help='list of comma separated keys for package to ignore')
-
-
- def adjust_options(options, args):
- pass
-
-
- def after_install(options, home_dir):
-
- global logger
-
- verbosity = options.verbose - options.quiet
- logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
+INSTALLS.extend([ #(key,method, option_str, dict_extra_env)
+ ('SETUPTOOLS-HG', 'pip', None, None),
+ ('MYSQL', 'pip', None, None),
+ ('PIL', 'easy_install', None, None),
+ ('DJANGO','pip', None, None),
+ ('JOGGING','pip', None, None),
+ ('DJANGO-EXTENSIONS', 'pip', None, None),
+ ('DJANGO-REGISTRATION', 'easy_install', '-Z', None),
+ ('DJANGO-TAGGING', 'pip', None, None),
+ ('DJANGO-PISTON', 'pip', None, None),
+ ('HTTPLIB2', 'pip', None, None),
+ ('OAUTH2', 'easy_install', None, None),
+ ('DJANGO-OAUTH-PLUS', 'pip', None, None),
+])
-
- home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
- base_dir = os.path.dirname(home_dir)
- src_dir = os.path.join(home_dir, 'src')
- tmp_dir = os.path.join(home_dir, 'tmp')
- ensure_dir(src_dir)
- ensure_dir(tmp_dir)
- system_str = platform.system()
-
- res_source_key = options.type_install
-
- ignore_packages = []
-
- if options.ignore_packages :
- ignore_packages = options.ignore_packages.split(",")
-
- logger.indent += 2
- try:
-
- if 'PYLUCENE' not in ignore_packages and system_str != "Windows":
- #get pylucene
- logger.notify("Get Pylucene from %s " % res_env.URLS['PYLUCENE'][res_source_key])
- pylucene_src = os.path.join(src_dir,"pylucene.tar.gz")
- if res_source_key == 'local':
- shutil.copy(res_env.URLS['PYLUCENE'][res_source_key], pylucene_src)
- else:
- urllib.urlretrieve(res_env.URLS['PYLUCENE'][res_source_key], pylucene_src)
- tf = tarfile.open(pylucene_src,'r:gz')
- pylucene_base_path = os.path.join(src_dir,"pylucene")
- logger.notify("Extract Pylucene to %s " % pylucene_base_path)
- tf.extractall(pylucene_base_path)
- tf.close()
-
- pylucene_src_path = os.path.join(pylucene_base_path, os.listdir(pylucene_base_path)[0])
- jcc_src_path = os.path.abspath(os.path.join(pylucene_src_path,"jcc"))
-
- #install jcc
-
- #patch for linux
- if system_str == 'Linux' :
- olddir = os.getcwd()
- patch_dest_path = os.path.join(lib_dir,'site-packages','setuptools-0.6c11-py'+'%s.%s' % (sys.version_info[0], sys.version_info[1])+'.egg')
- if os.path.isfile(patch_dest_path):
- # must unzip egg
- # rename file and etract all
- shutil.move(patch_dest_path, patch_dest_path + ".zip")
- zf = zipfile.ZipFile(patch_dest_path + ".zip",'r')
- zf.extractall(patch_dest_path)
- os.remove(patch_dest_path + ".zip")
- logger.notify("Patch jcc : %s " % (patch_dest_path))
- os.chdir(patch_dest_path)
- p = patch.fromfile(os.path.join(jcc_src_path,"jcc","patches","patch.43.0.6c11"))
- p.apply()
- os.chdir(olddir)
-
- logger.notify("Install jcc")
- call_subprocess([os.path.abspath(os.path.join(home_dir, 'bin', 'python')), 'setup.py', 'install'],
- cwd=jcc_src_path,
- filter_stdout=filter_python_develop,
- show_stdout=True)
- #install pylucene
-
- logger.notify("Install pylucene")
- #modify makefile
- makefile_path = os.path.join(pylucene_src_path,"Makefile")
- logger.notify("Modify makefile %s " % makefile_path)
- shutil.move( makefile_path, makefile_path+"~" )
-
- destination= open( makefile_path, "w" )
- source= open( makefile_path+"~", "r" )
- destination.write("PREFIX_PYTHON="+os.path.abspath(home_dir)+"\n")
- destination.write("ANT=ant\n")
- destination.write("PYTHON=$(PREFIX_PYTHON)/bin/python\n")
-
- if system_str == "Darwin":
- if sys.version_info >= (2,6):
- destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\n")
- else:
- destination.write("JCC=$(PYTHON) -m jcc --shared --arch x86_64 --arch i386\n")
- destination.write("NUM_FILES=2\n")
- elif system_str == "Windows":
- destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\n")
- destination.write("NUM_FILES=2\n")
- else:
- if sys.version_info >= (2,6) and sys.version_info <= (2,7):
- destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared\n")
- else:
- destination.write("JCC=$(PYTHON) -m jcc --shared\n")
- destination.write("NUM_FILES=2\n")
- for line in source:
- destination.write( line )
- source.close()
- destination.close()
- os.remove(makefile_path+"~" )
-
- logger.notify("pylucene make")
- call_subprocess(['make'],
- cwd=os.path.abspath(pylucene_src_path),
- filter_stdout=filter_python_develop,
- show_stdout=True)
-
- logger.notify("pylucene make install")
- call_subprocess(['make', 'install'],
- cwd=os.path.abspath(pylucene_src_path),
- filter_stdout=filter_python_develop,
- show_stdout=True)
-
-
- if 'PSYCOPG2' not in ignore_packages and system_str == "Windows":
- #get psycopg2
- psycopg2_src = os.path.join(src_dir,"psycopg2.zip")
- shutil.copy(res_env.URLS['PSYCOPG2'][res_source_key], psycopg2_src)
- #extract psycopg2
- zf = zipfile.ZipFile(psycopg2_src)
- psycopg2_base_path = os.path.join(src_dir,"psycopg2")
- zf.extractall(psycopg2_base_path)
- zf.close()
-
- psycopg2_src_path = os.path.join(psycopg2_base_path, os.listdir(psycopg2_base_path)[0])
- shutil.copytree(os.path.join(psycopg2_src_path, 'psycopg2'), os.path.abspath(os.path.join(home_dir, 'Lib', 'psycopg2')))
- shutil.copy(os.path.join(psycopg2_src_path, 'psycopg2-2.0.10-py2.6.egg-info'), os.path.abspath(os.path.join(home_dir, 'Lib', 'site-packages')))
-
- for key, method, option_str, extra_env in res_env.NORMAL_INSTALL:
- if key not in ignore_packages:
- normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir)
-
- logger.notify("Clear source dir")
- shutil.rmtree(src_dir)
-
- finally:
- logger.indent -= 2
- script_dir = join(base_dir, bin_dir)
- logger.notify('Run "%s Package" to install new packages that provide builds'
- % join(script_dir, 'easy_install'))
-
-
- def normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir):
- global logger
- logger.notify("Install %s from %s with %s" % (key,res_env.URLS[key][res_source_key],method))
- if method == 'pip':
- if sys.platform == 'win32':
- args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'pip')), 'install', '-E', os.path.abspath(home_dir), res_env.URLS[key][res_source_key]]
- else:
- args = [os.path.abspath(os.path.join(home_dir, 'bin', 'pip')), 'install', '-E', os.path.abspath(home_dir), res_env.URLS[key][res_source_key]]
- if option_str :
- args.insert(4,option_str)
- call_subprocess(args,
- cwd=os.path.abspath(tmp_dir),
- filter_stdout=filter_python_develop,
- show_stdout=True,
- extra_env=extra_env)
- else:
- if sys.platform == 'win32':
- args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'easy_install')), res_env.URLS[key][res_source_key]]
- else:
- args = [os.path.abspath(os.path.join(home_dir, 'bin', 'easy_install')), res_env.URLS[key][res_source_key]]
- if option_str :
- args.insert(1,option_str)
- call_subprocess(args,
- cwd=os.path.abspath(tmp_dir),
- filter_stdout=filter_python_develop,
- show_stdout=True,
- extra_env=extra_env)
-
-
- def ensure_dir(dir):
- global logger
- if not os.path.exists(dir):
- logger.notify('Creating directory %s' % dir)
- os.makedirs(dir)
-
- def filter_python_develop(line):
- if not line.strip():
- return Logger.DEBUG
- for prefix in ['Searching for', 'Reading ', 'Best match: ', 'Processing ',
- 'Moving ', 'Adding ', 'running ', 'writing ', 'Creating ',
- 'creating ', 'Copying ']:
- if line.startswith(prefix):
- return Logger.DEBUG
- return Logger.NOTIFY
+if system_str == 'Windows':
+ INSTALLS.extend([
+ ('JCC','easy_install',None,None),
+ ('PYLUCENE','easy_install',None,None),
+ ('PSYCOPG2',install_psycopg2,None,None),
+ ])
+else:
+ INSTALLS.extend([
+ ('PYLUCENE',install_pylucene,None,None),
+ ('PSYCOPG2', 'pip', None, None),
+ ])
- return adjust_options, extend_parser, after_install
+if system_str == "Darwin":
+ INSTALLS.extend([
+ ('LXML', 'pip', None, {'STATIC_DEPS': 'true', 'LIBXML2_VERSION': '2.7.8', 'LIBXSLT_VERSION': '1.1.26'}),
+ ])
+else:
+ INSTALLS.extend([
+ ('LXML', 'pip', None, None),
+ ])
+
+
+def generate_install_methods(path_locations, src_base, Logger, call_subprocess):
+ return lib_generate_install_methods(path_locations, src_base, Logger, call_subprocess, INSTALLS)
Binary file virtualenv/web/res/src/Django-1.2.4.tar.gz has changed
Binary file virtualenv/web/res/src/Imaging-1.1.7.tar.gz has changed
Binary file virtualenv/web/res/src/JCC-2.6-py2.6-win32.egg has changed
Binary file virtualenv/web/res/src/MySQL-python-1.2.3.tar.gz has changed
Binary file virtualenv/web/res/src/PIL-1.1.7.win32-py2.6.exe has changed
Binary file virtualenv/web/res/src/distribute-0.6.14.tar.gz has changed
Binary file virtualenv/web/res/src/django-extensions-0.6.tar.gz has changed
Binary file virtualenv/web/res/src/django-oauth-plus.tar.gz has changed
Binary file virtualenv/web/res/src/django-piston-0.2.2-modified.tar.gz has changed
Binary file virtualenv/web/res/src/django-registration.tar.gz has changed
Binary file virtualenv/web/res/src/django-tagging-0.3.1.tar.gz has changed
Binary file virtualenv/web/res/src/httplib2-0.6.0.tar.gz has changed
Binary file virtualenv/web/res/src/jogging-0.2.2.tar.gz has changed
Binary file virtualenv/web/res/src/lucene-3.0.2-py2.6-win32.egg has changed
Binary file virtualenv/web/res/src/lxml-2.2.8-py2.6-win32.egg has changed
Binary file virtualenv/web/res/src/lxml-2.2.8.tar.gz has changed
Binary file virtualenv/web/res/src/psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip has changed
Binary file virtualenv/web/res/src/psycopg2-2.3.2.tar.gz has changed
Binary file virtualenv/web/res/src/pylucene-3.0.3-1-src.tar.gz has changed
Binary file virtualenv/web/res/src/python-oauth2-1.2.1-modified.tar.gz has changed
Binary file virtualenv/web/res/src/setuptools_hg-0.2.tar.gz has changed