87
|
1 """my_install_data.py
|
|
2
|
|
3 Provides a more sophisticated facility to install data files
|
|
4 than distutils' install_data does.
|
|
5 You can specify your files as a template like in MANIFEST.in
|
|
6 and you have more control over the copy process.
|
|
7
|
|
8 Copyright 2000 by Rene Liebscher, Germany.
|
|
9
|
|
10 Permission is hereby granted, free of charge, to any person obtaining
|
|
11 a copy of this software and associated documentation files (the
|
|
12 "Software"), to deal in the Software without restriction, including
|
|
13 without limitation the rights to use, copy, modify, merge, publish,
|
|
14 distribute, sublicense, and/or sell copies of the Software, and to
|
|
15 permit persons to whom the Software is furnished to do so, subject to
|
|
16 the following conditions:
|
|
17
|
|
18 The above copyright notice and this permission notice shall be included
|
|
19 in all copies or substantial portions of the Software.
|
|
20
|
|
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
24 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
25 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
28
|
|
29 Note:
|
|
30 This licence is only for this file.
|
|
31 PyOpenGL has its own licence. (it is almost identical.)
|
|
32 """
|
|
33
|
|
34 # created 2000/08/01, Rene Liebscher <R.Liebscher@gmx.de>
|
|
35
|
|
36 ###########################################################################
|
|
37 # import some modules we need
|
|
38
|
|
39 import os,sys,string
|
|
40 from types import StringType,TupleType,ListType
|
|
41 from distutils.util import change_root
|
|
42 from distutils.filelist import FileList
|
|
43 from distutils.command.install_data import install_data
|
|
44
|
|
45 ###########################################################################
|
|
46 # a container class for our more sophisticated install mechanism
|
|
47
|
|
48 class Data_Files:
|
|
49 """ container for list of data files.
|
|
50 supports alternate base_dirs e.g. 'install_lib','install_header',...
|
|
51 supports a directory where to copy files
|
|
52 supports templates as in MANIFEST.in
|
|
53 supports preserving of paths in filenames
|
|
54 eg. foo/xyz is copied to base_dir/foo/xyz
|
|
55 supports stripping of leading dirs of source paths
|
|
56 eg. foo/bar1/xyz, foo/bar2/abc can be copied to bar1/xyz, bar2/abc
|
|
57 """
|
|
58
|
|
59 def __init__(self,base_dir=None,files=None,copy_to=None,template=None,preserve_path=0,strip_dirs=0):
|
|
60 self.base_dir = base_dir
|
|
61 self.files = files
|
|
62 self.copy_to = copy_to
|
|
63 self.template = template
|
|
64 self.preserve_path = preserve_path
|
|
65 self.strip_dirs = strip_dirs
|
|
66 self.finalized = 0
|
|
67
|
|
68 def warn (self, msg):
|
|
69 sys.stderr.write ("warning: %s: %s\n" %
|
|
70 ("install_data", msg))
|
|
71
|
|
72 def debug_print (self, msg):
|
|
73 """Print 'msg' to stdout if the global DEBUG (taken from the
|
|
74 DISTUTILS_DEBUG environment variable) flag is true.
|
|
75 """
|
|
76 from distutils.core import DEBUG
|
|
77 if DEBUG:
|
|
78 print msg
|
|
79
|
|
80
|
|
81 def finalize(self):
|
|
82 """ complete the files list by processing the given template """
|
|
83 if self.finalized:
|
|
84 return
|
|
85 if self.files == None:
|
|
86 self.files = []
|
|
87 if self.template != None:
|
|
88 if type(self.template) == StringType:
|
|
89 self.template = string.split(self.template,";")
|
|
90 filelist = FileList(self.warn,self.debug_print)
|
|
91 for line in self.template:
|
|
92 filelist.process_template_line(string.strip(line))
|
|
93 filelist.sort()
|
|
94 filelist.remove_duplicates()
|
|
95 self.files.extend(filelist.files)
|
|
96 self.finalized = 1
|
|
97
|
|
98 # end class Data_Files
|
|
99
|
|
100 ###########################################################################
|
|
101 # a more sophisticated install routine than distutils install_data
|
|
102
|
|
103 class my_install_data (install_data):
|
|
104
|
|
105 def check_data(self,d):
|
|
106 """ check if data are in new format, if not create a suitable object.
|
|
107 returns finalized data object
|
|
108 """
|
|
109 if not isinstance(d, Data_Files):
|
|
110 self.warn(("old-style data files list found "
|
|
111 "-- please convert to Data_Files instance"))
|
|
112 if type(d) is TupleType:
|
|
113 if len(d) != 2 or not (type(d[1]) is ListType):
|
|
114 raise DistutilsSetupError, \
|
|
115 ("each element of 'data_files' option must be an "
|
|
116 "Data File instance, a string or 2-tuple (string,[strings])")
|
|
117 d = Data_Files(copy_to=d[0],files=d[1])
|
|
118 else:
|
|
119 if not (type(d) is StringType):
|
|
120 raise DistutilsSetupError, \
|
|
121 ("each element of 'data_files' option must be an "
|
|
122 "Data File instance, a string or 2-tuple (string,[strings])")
|
|
123 d = Data_Files(files=[d])
|
|
124 d.finalize()
|
|
125 return d
|
|
126
|
|
127 def run(self):
|
|
128 self.outfiles = []
|
|
129 install_cmd = self.get_finalized_command('install')
|
|
130
|
|
131 for d in self.data_files:
|
|
132 d = self.check_data(d)
|
|
133
|
|
134 install_dir = self.install_dir
|
|
135 # alternative base dir given => overwrite install_dir
|
|
136 if d.base_dir != None:
|
|
137 install_dir = getattr(install_cmd,d.base_dir)
|
|
138
|
|
139 # copy to an other directory
|
|
140 if d.copy_to != None:
|
|
141 if not os.path.isabs(d.copy_to):
|
|
142 # relatiev path to install_dir
|
|
143 dir = os.path.join(install_dir, d.copy_to)
|
|
144 elif install_cmd.root:
|
|
145 # absolute path and alternative root set
|
|
146 dir = change_root(self.root,d.copy_to)
|
|
147 else:
|
|
148 # absolute path
|
|
149 dir = d.copy_to
|
|
150 else:
|
|
151 # simply copy to install_dir
|
|
152 dir = install_dir
|
|
153 # warn if necceassary
|
|
154 self.warn("setup script did not provide a directory to copy files to "
|
|
155 " -- installing right in '%s'" % install_dir)
|
|
156
|
|
157 dir=os.path.normpath(dir)
|
|
158 # create path
|
|
159 self.mkpath(dir)
|
|
160
|
|
161 # copy all files
|
|
162 for src in d.files:
|
|
163 if d.strip_dirs > 0:
|
|
164 dst = string.join(string.split(src,os.sep)[d.strip_dirs:],os.sep)
|
|
165 else:
|
|
166 dst = src
|
|
167 if d.preserve_path:
|
|
168 # preserve path in filename
|
|
169 self.mkpath(os.path.dirname(os.path.join(dir,dst)))
|
|
170 out = self.copy_file(src, os.path.join(dir,dst))
|
|
171 else:
|
|
172 out = self.copy_file(src, dir)
|
|
173 if type(out) is TupleType:
|
|
174 out = out[0]
|
|
175 self.outfiles.append(out)
|
|
176
|
|
177 return self.outfiles
|
|
178
|
|
179 def get_inputs (self):
|
|
180 inputs = []
|
|
181 for d in self.data_files:
|
|
182 d = self.check_data(d)
|
|
183 inputs.append(d.files)
|
|
184 return inputs
|
|
185
|
|
186 def get_outputs (self):
|
|
187 return self.outfiles
|
|
188
|
|
189
|
|
190 ###########################################################################
|
|
191
|