"""distutils.command.install_scripts Implements the Distutils 'install_scripts' command, for installing Python scripts.""" # contributed by Bastian Kleineidam # This module should be kept compatible with Python 2.1. __revision__ = "$Id: install_scripts.py 37828 2004-11-10 22:23:15Z loewis $" import os import sys from distutils.core import Command from distutils.spawn import find_executable from distutils import log from stat import ST_MODE from string import Template class install_scripts (Command): description = "install scripts (Python or otherwise)" user_options = [ ('install-dir=', 'd', "directory to install scripts to"), ('build-dir=','b', "build directory (where to install from)"), ('force', 'f', "force installation (overwrite existing files)"), ('skip-build', None, "skip the build steps"), ] boolean_options = ['force', 'skip-build'] def initialize_options (self): self.install_dir = None self.force = 0 self.build_dir = None self.skip_build = None def finalize_options (self): self.set_undefined_options('build', ('build_scripts', 'build_dir')) self.set_undefined_options('install', ('install_scripts', 'install_dir'), ('force', 'force'), ('skip_build', 'skip_build'), ) def run (self): if not self.skip_build: self.run_command('build_scripts') self.outfiles = self.copy_tree(self.build_dir, self.install_dir) if os.name == 'posix': # Set the executable bits (owner, group, and world) on # all the scripts we just installed. for file in self.get_outputs(): if self.dry_run: log.info("changing mode of %s", file) else: mode = ((os.stat(file)[ST_MODE]) | 0555) & 07777 log.info("changing mode of %s to %o", file, mode) os.chmod(file, mode) elif os.name == 'nt': # Add .bat files for scripts without executables for file in self.get_outputs(): name = os.path.splitext(os.path.basename(file))[0] if not find_executable(name, path=self.install_dir): executable = "%s.bat" % os.path.join(self.install_dir, name) log.info("writing script executable %s", executable) t = Template("""\ @REM $name $version ($date) @REM $description @REM @REM $author <$author_email> @echo off set SCRIPT_ERRORLEVEL= if "%OS%" == "Windows_NT" goto WinNT @REM for 9x/Me you better not have more than 9 args $python $script %1 %2 %3 %4 %5 %6 %7 %8 %9 @REM no way to set exit status of this script for 9x/Me exit :WinNT @REM Credit where credit is due: we return the exit code despite our @REM use of setlocal+endlocal using a technique from Bear's Journal: @REM http://code-bear.com/bearlog/2007/06/01/getting-the-exit-code-from-a-batch-file-that-is-run-from-a-python-program/ setlocal @REM ensure the script will be executed with the Python it was installed for set path=%~dp0;%~dp0..;%path% python $script %* endlocal & set SCRIPT_ERRORLEVEL=%ERRORLEVEL% if NOT "%COMSPEC%" == "%SystemRoot%\\system32\\cmd.exe" goto returncode if errorlevel 9009 echo You do not have python in your PATH. goto endscript :returncode exit /B %SCRIPT_ERRORLEVEL% :endscript call :returncode %SCRIPT_ERRORLEVEL% """) d = dict(python=sys.executable, script=file) bf = open(executable, "wb") bf.write(t.safe_substitute(d)) def get_inputs (self): return self.distribution.scripts or [] def get_outputs(self): return self.outfiles or [] # class install_scripts