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

Reply via email to