build_py.py revision 71eb8644d7e27fd379a2cf78c509155bdb179332
113ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward"""distutils.command.build_py
213ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
313ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg WardImplements the Distutils 'build_py' command."""
413ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
513ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward# created 1999/03/08, Greg Ward
613ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward__rcsid__ = "$Id$"
813ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
913ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Wardimport string, os
1013ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Wardfrom distutils.core import Command
1113ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Wardfrom distutils.errors import *
1213ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Wardfrom distutils.util import mkpath, newer, make_file, copy_file
1313ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
1413ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
1513ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Wardclass BuildPy (Command):
1613ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
1713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward    options = [('dir=', 'd', "directory for platform-shared files"),
1813ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward              ]
1913ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
2013ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
2113ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward    def set_default_options (self):
2213ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        self.dir = None
2371eb8644d7e27fd379a2cf78c509155bdb179332Greg Ward        self.modules = None
2471eb8644d7e27fd379a2cf78c509155bdb179332Greg Ward        self.package = None
2513ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
2613ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward    def set_final_options (self):
2713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        self.set_undefined_options ('build',
280f72695da324d4cc24ebbeb4873c23d01f97f861Greg Ward                                    ('libdir', 'dir'))
2971eb8644d7e27fd379a2cf78c509155bdb179332Greg Ward        if self.package is None:
3071eb8644d7e27fd379a2cf78c509155bdb179332Greg Ward            self.package = ''
3113ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
3213ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
3313ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward    def run (self):
3413ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
3513ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # XXX copy_file by default preserves all stat info -- mode, atime,
3613ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # and mtime.  IMHO this is the right thing to do, but perhaps it
3713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # should be an option -- in particular, a site administrator might
3813ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # want installed files to reflect the time of installation rather
3913ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # than the last modification time before the installed release.
4013ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
4113ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # XXX copy_file does *not* preserve MacOS-specific file metadata.
4213ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # If this is a problem for building/installing Python modules, then
4313ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # we'll have to fix copy_file.  (And what about installing scripts,
4413ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # when the time comes for that -- does MacOS use its special
4513ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # metadata to know that a file is meant to be interpreted by
4613ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # Python?)
4713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
4813ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        self.set_final_options ()
4913ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
5013ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        infiles = []
5113ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        outfiles = []
5213ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        missing = []
5313ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
5413ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # Loop over the list of "pure Python" modules, deriving
5513ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # input and output filenames and checking for missing
5613ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # input files.
5713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
585d60fcf02a7050a07067a12c7a98c8b6b1e68372Greg Ward        # it's ok not to have *any* py files, right?
5971eb8644d7e27fd379a2cf78c509155bdb179332Greg Ward        if not self.modules:
605d60fcf02a7050a07067a12c7a98c8b6b1e68372Greg Ward            return
615d60fcf02a7050a07067a12c7a98c8b6b1e68372Greg Ward
6213ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # XXX we should allow for wildcards, so eg. the Distutils setup.py
6313ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # file would just have to say
6413ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        #   py_modules = ['distutils.*', 'distutils.command.*']
6513ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # without having to list each one explicitly.
6671eb8644d7e27fd379a2cf78c509155bdb179332Greg Ward        for m in self.modules:
6713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward            fn = apply (os.path.join, tuple (string.split (m, '.'))) + '.py'
6813ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward            if not os.path.exists (fn):
6913ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward                missing.append (fn)
7013ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward            else:
7113ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward                infiles.append (fn)
7271eb8644d7e27fd379a2cf78c509155bdb179332Greg Ward                outfiles.append (os.path.join (self.dir, self.package, fn))
7313ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
7413ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # Blow up if any input files were not found.
7513ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        if missing:
7613ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward            raise DistutilsFileError, \
7713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward                  "missing files: " + string.join (missing, ' ')
7813ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
7913ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # Loop over the list of input files, copying them to their
8013ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        # temporary (build) destination.
8113ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        created = {}
8213ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward        for i in range (len (infiles)):
8313ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward            outdir = os.path.split (outfiles[i])[0]
8413ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward            if not created.get(outdir):
854070f50537fd1945d2ecbb9d4e72aeba7e72fa55Greg Ward                self.mkpath (outdir)
8613ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward                created[outdir] = 1
8713ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
884070f50537fd1945d2ecbb9d4e72aeba7e72fa55Greg Ward            self.copy_file (infiles[i], outfiles[i])
8913ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward
9013ae1c8ff81befcfd0b0ece98ef471cd504642d8Greg Ward# end class BuildPy
91