Well, I gave this a first go. I've attached a diff, but I'm not
actually advocating that it go in.
In this, you have to explicitly give the package name, because it's
often not clear from the download location. So here's two examples:
python easy_install.py --force-package=flup -d app-packages/
http://svn.saddi.com/flup/trunk/flup
python easy_install.py --force-package=Component -d app-packages/
http://svn.w4py.org/Component/trunk
Hrm... but I don't really like it. First, force_package is passed into
Installer.__init__, and it should be part of the spec. Also, I don't
think you always need to explicitly give the package name, sometimes it
is self-evident. Also it doesn't work with plain Python files, which
can't even be properly downloaded at this point, and for which eggs seem
a little excessive. (To give an example of a single file I'd like to be
able to install:
http://bellsouthpwp.net/m/e/mefjr75/python/PySourceColor.py)
I'm thinking maybe a better way to do this would be some sort of patch
process, so that I could distribute a setup.py seperately, or some other
custom build process, that easy_install could detect and run.
And, of course, obviously I *could* fix these upstream, but I think this
is a useful problem to solve through easy_install, even if these
particular packages get fixed later.
--
Ian Bicking / [EMAIL PROTECTED] / http://blog.ianbicking.org
--- orig/setuptools-0.3a2/easy_install.py 2005-05-29 18:01:42.000000000
-0500
+++ easy_install.py 2005-05-29 21:28:03.357133760 -0500
@@ -151,6 +151,10 @@
directory is on ``sys.path`` at runtime, and to use
``pkg_resources.require()`` to enable the installed package(s) that you
need.
+
+``--force-package=PACKAGE_NAME``
+ If the downloaded package doesn't include a ``setup.py`` file, then it
+ will be installed as a simple package.
"""
import sys, os.path, pkg_resources, re, zipimport, zipfile, tarfile, shutil
@@ -167,7 +171,8 @@
pth_file = None
- def __init__(self, instdir=None, zip_ok=False, multi=None, tmpdir=None):
+ def __init__(self, instdir=None, zip_ok=False, multi=None, tmpdir=None,
+ force_package=None):
if tmpdir is None:
from tempfile import mkdtemp
@@ -193,9 +198,11 @@
self.instdir = instdir
self.zip_ok = zip_ok
self.multi = multi
+ self.force_package = force_package
def close(self):
if os.path.isdir(self.tmpdir):
+ return
rmtree(self.tmpdir,True)
def __del__(self):
@@ -258,6 +265,9 @@
setup_script = os.path.join(self.tmpdir, 'setup.py')
if not os.path.exists(setup_script):
setups = glob(os.path.join(self.tmpdir, '*', 'setup.py'))
+ if not setups and self.force_package:
+ self._create_forced_setup(setup_script)
+ setups = [setup_script]
if not setups:
raise RuntimeError(
"Couldn't find a setup script in %s" % dist_filename
@@ -326,6 +336,32 @@
finally:
tarobj.close()
+ def _create_forced_setup(self, filename):
+ from glob import glob
+ package_name = self.force_package
+ f = open(filename, 'w')
+ f.write('from distutils.core import setup\n\n')
+ attrs = {}
+ attrs['name'] = package_name
+ dirs = []
+ package_dirs = glob(os.path.join(self.tmpdir, '*', '__init__.py'))
+ if not package_dirs:
+ raise RuntimeError(
+ "No directories found with __init__.py files")
+ packages = [os.path.dirname(d[len(self.tmpdir):].lstrip(os.sep)) for d
in package_dirs]
+ pkg_dir_name = None
+ for package in packages:
+ pkg_name = package.split('.')[0]
+ if pkg_dir_name and pkg_name != pkg_dir_name:
+ raise RuntimeError(
+ "More than one potential package directory (%r and %r)"
+ % (pkg_dir_name, pkg_name))
+ pkg_dir_name = pkg_name
+ attrs['packages'] = ['.'.join([package_name] + d.split(os.sep)[1:])
for d in packages]
+ attrs['package_dir'] = {package_name: pkg_dir_name}
+ f.write('setup(**%r)' % attrs)
+ f.close()
+
def _run_setup(self, setup_script):
from setuptools.command import bdist_egg
sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg)
@@ -547,6 +583,9 @@
parser.add_option("-m", "--multi-version",
action="store_true", dest="multi", default=None,
help="make apps have to require() a version")
+ parser.add_option("--force-package",
+ dest="force_package", default=None,
metavar="PACKAGE_NAME",
+ help="install as a package (with name PACKAGE_NAME) even
if setup.py is missing")
(options, args) = parser.parse_args()
@@ -555,7 +594,8 @@
parser.error("No urls, filenames, or requirements specified")
for spec in args:
- inst = factory(options.instdir, options.zip_ok, options.multi)
+ inst = factory(options.instdir, options.zip_ok, options.multi,
+ force_package=options.force_package)
try:
print "Downloading", spec
downloaded = inst.download(spec)
_______________________________________________
Distutils-SIG maillist - [email protected]
http://mail.python.org/mailman/listinfo/distutils-sig