[Distutils] Re: Including an empty directory

Konrad Hinsen hinsen@cnrs-orleans.fr
Tue Apr 3 09:14:01 2001


> Hmm... looks like you can't.  If a file fails an os.path.isfile()
> check, sdist.py skips it and prints a warning.  That's probably worth
> loosening.  Creating directories makes sense, but I don't think we
> need to support symlinks or more exotic file types such as pipes.

Here are the necessary patches from my setup.py:

   from distutils.core import setup, Extension
   from distutils.command.sdist import sdist
   from distutils import dir_util
   from distutils.filelist import FileList, translate_pattern

   class ModifiedFileList(FileList):

       def findall(self, dir=os.curdir):
	   from stat import ST_MODE, S_ISREG, S_ISDIR, S_ISLNK
	   list = []
	   stack = [dir]
	   pop = stack.pop
	   push = stack.append
	   while stack:
	       dir = pop()
	       names = os.listdir(dir)
	       for name in names:
		   if dir != os.curdir:        # avoid the dreaded "./" syndrome
		       fullname = os.path.join(dir, name)
		   else:
		       fullname = name
		   stat = os.stat(fullname)
		   mode = stat[ST_MODE]
		   if S_ISREG(mode):
		       list.append(fullname)
		   elif S_ISDIR(mode) and not S_ISLNK(mode):
		       list.append(fullname)
		       push(fullname)
	   self.allfiles = list

   class modified_sdist(sdist):

       def run (self):

	   self.filelist = ModifiedFileList()
	   self.check_metadata()
	   self.get_file_list()
	   if self.manifest_only:
	       return
	   self.make_distribution()

       def make_release_tree (self, base_dir, files):
	   self.mkpath(base_dir)
	   dir_util.create_tree(base_dir, files,
				verbose=self.verbose, dry_run=self.dry_run)
	   if hasattr(os, 'link'):        # can make hard links on this system
	       link = 'hard'
	       msg = "making hard links in %s..." % base_dir
	   else:                           # nope, have to copy
	       link = None
	       msg = "copying files to %s..." % base_dir
	   if not files:
	       self.warn("no files to distribute -- empty manifest?")
	   else:
	       self.announce(msg)
	   for file in files:
	       if os.path.isfile(file):
		   dest = os.path.join(base_dir, file)
		   self.copy_file(file, dest, link=link)
	       elif os.path.isdir(file):
		   dir_util.mkpath(os.path.join(base_dir, file))
	       else:
		   self.warn("'%s' not a regular file or directory -- skipping"
			     % file)

   setup(...
	 cmdclass = {'sdist': modified_sdist})

I am not too happy with this kind of patching, as I rely quite a bit
on undocumented internals of Distutils, which might change in future
versions. But for the moment I seem to have no other choice.

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                            | E-Mail: hinsen@cnrs-orleans.fr
Centre de Biophysique Moleculaire (CNRS) | Tel.: +33-2.38.25.56.24
Rue Charles Sadron                       | Fax:  +33-2.38.63.15.17
45071 Orleans Cedex 2                    | Deutsch/Esperanto/English/
France                                   | Nederlands/Francais
-------------------------------------------------------------------------------