|
4068
|
1 #
|
|
|
2 # Copyright (C) 2009 Stefan Seefeld
|
|
|
3 # All rights reserved.
|
|
|
4 # For license terms see the file COPYING.txt.
|
|
|
5 #
|
|
|
6 from distutils.command.build_scripts import build_scripts as base
|
|
|
7 import sys, os, string
|
|
|
8
|
|
|
9 class build_scripts(base):
|
|
|
10 """ Overload the build_scripts command and create the scripts
|
|
|
11 from scratch, depending on the target platform.
|
|
|
12
|
|
|
13 You have to define the name of your package in an inherited
|
|
|
14 class (due to the delayed instantiation of command classes
|
|
|
15 in distutils, this cannot be passed to __init__).
|
|
|
16
|
|
|
17 The scripts are created in an uniform scheme: they start the
|
|
|
18 run() function in the module
|
|
|
19
|
|
|
20 <packagename>.scripts.<mangled_scriptname>
|
|
|
21
|
|
|
22 The mangling of script names replaces '-' and '/' characters
|
|
|
23 with '-' and '.', so that they are valid module paths.
|
|
|
24
|
|
|
25 If the target platform is win32, create .bat files instead of
|
|
|
26 *nix shell scripts. Target platform is set to "win32" if main
|
|
|
27 command is 'bdist_wininst' or if the command is 'bdist' and
|
|
|
28 it has the list of formats (from command line or config file)
|
|
|
29 and the first item on that list is wininst. Otherwise
|
|
|
30 target platform is set to current (build) platform.
|
|
|
31 """
|
|
|
32 package_name = 'roundup'
|
|
|
33
|
|
|
34 def initialize_options(self):
|
|
|
35 base.initialize_options(self)
|
|
|
36 self.script_preamble = None
|
|
|
37 self.target_platform = None
|
|
|
38 self.python_executable = None
|
|
|
39
|
|
|
40 def finalize_options(self):
|
|
|
41 base.finalize_options(self)
|
|
|
42 cmdopt=self.distribution.command_options
|
|
|
43
|
|
|
44 # find the target platform
|
|
|
45 if self.target_platform:
|
|
|
46 # TODO? allow explicit setting from command line
|
|
|
47 target = self.target_platform
|
|
|
48 if cmdopt.has_key("bdist_wininst"):
|
|
|
49 target = "win32"
|
|
|
50 elif cmdopt.get("bdist", {}).has_key("formats"):
|
|
|
51 formats = cmdopt["bdist"]["formats"][1].split(",")
|
|
|
52 if formats[0] == "wininst":
|
|
|
53 target = "win32"
|
|
|
54 else:
|
|
|
55 target = sys.platform
|
|
|
56 if len(formats) > 1:
|
|
|
57 self.warn(
|
|
|
58 "Scripts are built for %s only (requested formats: %s)"
|
|
|
59 % (target, ",".join(formats)))
|
|
|
60 else:
|
|
|
61 # default to current platform
|
|
|
62 target = sys.platform
|
|
|
63 self.target_platfom = target
|
|
|
64
|
|
|
65 # for native builds, use current python executable path;
|
|
|
66 # for cross-platform builds, use default executable name
|
|
|
67 if self.python_executable:
|
|
|
68 # TODO? allow command-line option
|
|
|
69 pass
|
|
|
70 if target == sys.platform:
|
|
|
71 self.python_executable = os.path.normpath(sys.executable)
|
|
|
72 else:
|
|
|
73 self.python_executable = "python"
|
|
|
74
|
|
|
75 # for windows builds, add ".bat" extension
|
|
|
76 if target == "win32":
|
|
|
77 # *nix-like scripts may be useful also on win32 (cygwin)
|
|
|
78 # to build both script versions, use:
|
|
|
79 #self.scripts = list(self.scripts) + [script + ".bat"
|
|
|
80 # for script in self.scripts]
|
|
|
81 self.scripts = [script + ".bat" for script in self.scripts]
|
|
|
82
|
|
|
83 # tweak python path for installations outside main python library
|
|
|
84 if cmdopt.get("install", {}).has_key("prefix"):
|
|
|
85 prefix = os.path.expanduser(cmdopt['install']['prefix'][1])
|
|
|
86 version = '%d.%d'%sys.version_info[:2]
|
|
|
87 self.script_preamble = """
|
|
|
88 import sys
|
|
|
89 sys.path.insert(1, "%s/lib/python%s/site-packages")
|
|
|
90 """%(prefix, version)
|
|
|
91 else:
|
|
|
92 self.script_preamble = ''
|
|
|
93
|
|
|
94 def copy_scripts(self):
|
|
|
95 """ Create each script listed in 'self.scripts'
|
|
|
96 """
|
|
|
97
|
|
|
98 to_module = string.maketrans('-/', '_.')
|
|
|
99
|
|
|
100 self.mkpath(self.build_dir)
|
|
|
101 for script in self.scripts:
|
|
|
102 outfile = os.path.join(self.build_dir, os.path.basename(script))
|
|
|
103
|
|
|
104 #if not self.force and not newer(script, outfile):
|
|
|
105 # self.announce("not copying %s (up-to-date)" % script)
|
|
|
106 # continue
|
|
|
107
|
|
|
108 if self.dry_run:
|
|
|
109 self.announce("would create %s" % outfile)
|
|
|
110 continue
|
|
|
111
|
|
|
112 module = os.path.splitext(os.path.basename(script))[0]
|
|
|
113 module = string.translate(module, to_module)
|
|
|
114 script_vars = {
|
|
|
115 'python': self.python_executable,
|
|
|
116 'package': self.package_name,
|
|
|
117 'module': module,
|
|
|
118 'prefix': self.script_preamble,
|
|
|
119 }
|
|
|
120
|
|
|
121 self.announce("creating %s" % outfile)
|
|
|
122 file = open(outfile, 'w')
|
|
|
123
|
|
|
124 try:
|
|
|
125 # could just check self.target_platform,
|
|
|
126 # but looking at the script extension
|
|
|
127 # makes it possible to build both *nix-like
|
|
|
128 # and windows-like scripts on win32.
|
|
|
129 # may be useful for cygwin.
|
|
|
130 if os.path.splitext(outfile)[1] == ".bat":
|
|
|
131 file.write('@echo off\n'
|
|
|
132 'if NOT "%%_4ver%%" == "" "%(python)s" -c "from %(package)s.scripts.%(module)s import run; run()" %%$\n'
|
|
|
133 'if "%%_4ver%%" == "" "%(python)s" -c "from %(package)s.scripts.%(module)s import run; run()" %%*\n'
|
|
|
134 % script_vars)
|
|
|
135 else:
|
|
|
136 file.write('#! %(python)s\n%(prefix)s'
|
|
|
137 'from %(package)s.scripts.%(module)s import run\n'
|
|
|
138 'run()\n'
|
|
|
139 % script_vars)
|
|
|
140 finally:
|
|
|
141 file.close()
|
|
|
142 os.chmod(outfile, 0755)
|