"""distutils.command.build_scripts

Implements the Distutils 'build_scripts' command."""

# created 2000/05/23, Bastian Kleineidam

__revision__ = "$Id$"

import sys, os, re
from distutils.core import Command
from distutils.dep_util import newer

# check if Python is called on the first line with this expression
first_line_re = re.compile(r'^#!.*python(\s+.*)?')

class build_scripts (Command):

    description = "\"build\" scripts (copy and fixup #! line)"

    user_options = [
        ('build-dir=', 'd', "directory to \"build\" (copy) to"),
        ('force', 'f', "forcibly build everything (ignore file timestamps"),
        ]


    def initialize_options (self):
        self.build_dir = None
        self.scripts = None
        self.force = None
        self.outfiles = None

    def finalize_options (self):
        self.set_undefined_options ('build',
                                    ('build_scripts', 'build_dir'),
                                    ('force', 'force'))
        self.scripts = self.distribution.scripts


    def run (self):
        if not self.scripts:
            return
        self.copy_scripts()

        
    def copy_scripts (self):
        """Copy each script listed in 'self.scripts'; if it's marked as a
        Python script in the Unix way (first line matches 'first_line_re',
        ie. starts with "\#!" and contains "python"), then adjust the first
        line to refer to the current Python interpreter as we copy.
        """
        outfiles = []
        self.mkpath(self.build_dir)
        for script in self.scripts:
            adjust = 0
            outfile = os.path.join(self.build_dir, os.path.basename(script))

            if not self.force and not newer(script, outfile):
                self.announce("not copying %s (output up-to-date)" % script)
                continue

            # Always open the file, but ignore failures in dry-run mode --
            # that way, we'll get accurate feedback if we can read the
            # script.
            try:
                f = open(script, "r")
            except IOError:
                if not self.dry_run:
                    raise
                f = None
            else:
                first_line = f.readline()
                if not first_line:
                    self.warn("%s is an empty file (skipping)" % script)
                    continue

                match = first_line_re.match(first_line)
                if match:
                    adjust = 1
                    post_interp = match.group(1)

            if adjust:
                self.announce("copying and adjusting %s -> %s" %
                              (script, self.build_dir))
                if not self.dry_run:
                    outf = open(outfile, "w")
                    outf.write("#!%s%s\n" % 
                               (os.path.normpath(sys.executable), post_interp))
                    outf.writelines(f.readlines())
                    outf.close()
                if f:
                    f.close()
            else:
                f.close()
                self.copy_file(script, outfile)

    # copy_scripts ()

# class build_scripts
