##// END OF EJS Templates
Check return value of all directory-finding functions is unicode....
Thomas Kluyver -
Show More
@@ -1,395 +1,401 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Utilities for path handling.
3 Utilities for path handling.
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import os
17 import os
18 import sys
18 import sys
19
19
20 import IPython
20 import IPython
21 from IPython.utils.process import system
21 from IPython.utils.process import system
22 from IPython.utils.importstring import import_item
22 from IPython.utils.importstring import import_item
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Code
25 # Code
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 # in case filesystemencoding() returns None:
28 fs_encoding = sys.getfilesystemencoding()
29 fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
29
30 def _cast_unicode(s, enc=None):
31 """Turn 8-bit strings into unicode."""
32 if isinstance(s, bytes):
33 enc = enc or sys.getdefaultencoding()
34 return s.decode(enc)
35 return s
36
30
37
31 def _get_long_path_name(path):
38 def _get_long_path_name(path):
32 """Dummy no-op."""
39 """Dummy no-op."""
33 return path
40 return path
34
41
35
36 if sys.platform == 'win32':
42 if sys.platform == 'win32':
37 def _get_long_path_name(path):
43 def _get_long_path_name(path):
38 """Get a long path name (expand ~) on Windows using ctypes.
44 """Get a long path name (expand ~) on Windows using ctypes.
39
45
40 Examples
46 Examples
41 --------
47 --------
42
48
43 >>> get_long_path_name('c:\\docume~1')
49 >>> get_long_path_name('c:\\docume~1')
44 u'c:\\\\Documents and Settings'
50 u'c:\\\\Documents and Settings'
45
51
46 """
52 """
47 try:
53 try:
48 import ctypes
54 import ctypes
49 except ImportError:
55 except ImportError:
50 raise ImportError('you need to have ctypes installed for this to work')
56 raise ImportError('you need to have ctypes installed for this to work')
51 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
57 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
52 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
58 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
53 ctypes.c_uint ]
59 ctypes.c_uint ]
54
60
55 buf = ctypes.create_unicode_buffer(260)
61 buf = ctypes.create_unicode_buffer(260)
56 rv = _GetLongPathName(path, buf, 260)
62 rv = _GetLongPathName(path, buf, 260)
57 if rv == 0 or rv > 260:
63 if rv == 0 or rv > 260:
58 return path
64 return path
59 else:
65 else:
60 return buf.value
66 return buf.value
61
67
62
68
63 def get_long_path_name(path):
69 def get_long_path_name(path):
64 """Expand a path into its long form.
70 """Expand a path into its long form.
65
71
66 On Windows this expands any ~ in the paths. On other platforms, it is
72 On Windows this expands any ~ in the paths. On other platforms, it is
67 a null operation.
73 a null operation.
68 """
74 """
69 return _get_long_path_name(path)
75 return _get_long_path_name(path)
70
76
71
77
72 def get_py_filename(name):
78 def get_py_filename(name):
73 """Return a valid python filename in the current directory.
79 """Return a valid python filename in the current directory.
74
80
75 If the given name is not a file, it adds '.py' and searches again.
81 If the given name is not a file, it adds '.py' and searches again.
76 Raises IOError with an informative message if the file isn't found."""
82 Raises IOError with an informative message if the file isn't found."""
77
83
78 name = os.path.expanduser(name)
84 name = os.path.expanduser(name)
79 if not os.path.isfile(name) and not name.endswith('.py'):
85 if not os.path.isfile(name) and not name.endswith('.py'):
80 name += '.py'
86 name += '.py'
81 if os.path.isfile(name):
87 if os.path.isfile(name):
82 return name
88 return name
83 else:
89 else:
84 raise IOError,'File `%s` not found.' % name
90 raise IOError,'File `%s` not found.' % name
85
91
86
92
87 def filefind(filename, path_dirs=None):
93 def filefind(filename, path_dirs=None):
88 """Find a file by looking through a sequence of paths.
94 """Find a file by looking through a sequence of paths.
89
95
90 This iterates through a sequence of paths looking for a file and returns
96 This iterates through a sequence of paths looking for a file and returns
91 the full, absolute path of the first occurence of the file. If no set of
97 the full, absolute path of the first occurence of the file. If no set of
92 path dirs is given, the filename is tested as is, after running through
98 path dirs is given, the filename is tested as is, after running through
93 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
99 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
94
100
95 filefind('myfile.txt')
101 filefind('myfile.txt')
96
102
97 will find the file in the current working dir, but::
103 will find the file in the current working dir, but::
98
104
99 filefind('~/myfile.txt')
105 filefind('~/myfile.txt')
100
106
101 Will find the file in the users home directory. This function does not
107 Will find the file in the users home directory. This function does not
102 automatically try any paths, such as the cwd or the user's home directory.
108 automatically try any paths, such as the cwd or the user's home directory.
103
109
104 Parameters
110 Parameters
105 ----------
111 ----------
106 filename : str
112 filename : str
107 The filename to look for.
113 The filename to look for.
108 path_dirs : str, None or sequence of str
114 path_dirs : str, None or sequence of str
109 The sequence of paths to look for the file in. If None, the filename
115 The sequence of paths to look for the file in. If None, the filename
110 need to be absolute or be in the cwd. If a string, the string is
116 need to be absolute or be in the cwd. If a string, the string is
111 put into a sequence and the searched. If a sequence, walk through
117 put into a sequence and the searched. If a sequence, walk through
112 each element and join with ``filename``, calling :func:`expandvars`
118 each element and join with ``filename``, calling :func:`expandvars`
113 and :func:`expanduser` before testing for existence.
119 and :func:`expanduser` before testing for existence.
114
120
115 Returns
121 Returns
116 -------
122 -------
117 Raises :exc:`IOError` or returns absolute path to file.
123 Raises :exc:`IOError` or returns absolute path to file.
118 """
124 """
119
125
120 # If paths are quoted, abspath gets confused, strip them...
126 # If paths are quoted, abspath gets confused, strip them...
121 filename = filename.strip('"').strip("'")
127 filename = filename.strip('"').strip("'")
122 # If the input is an absolute path, just check it exists
128 # If the input is an absolute path, just check it exists
123 if os.path.isabs(filename) and os.path.isfile(filename):
129 if os.path.isabs(filename) and os.path.isfile(filename):
124 return filename
130 return filename
125
131
126 if path_dirs is None:
132 if path_dirs is None:
127 path_dirs = ("",)
133 path_dirs = ("",)
128 elif isinstance(path_dirs, basestring):
134 elif isinstance(path_dirs, basestring):
129 path_dirs = (path_dirs,)
135 path_dirs = (path_dirs,)
130
136
131 for path in path_dirs:
137 for path in path_dirs:
132 if path == '.': path = os.getcwd()
138 if path == '.': path = os.getcwd()
133 testname = expand_path(os.path.join(path, filename))
139 testname = expand_path(os.path.join(path, filename))
134 if os.path.isfile(testname):
140 if os.path.isfile(testname):
135 return os.path.abspath(testname)
141 return os.path.abspath(testname)
136
142
137 raise IOError("File %r does not exist in any of the search paths: %r" %
143 raise IOError("File %r does not exist in any of the search paths: %r" %
138 (filename, path_dirs) )
144 (filename, path_dirs) )
139
145
140
146
141 class HomeDirError(Exception):
147 class HomeDirError(Exception):
142 pass
148 pass
143
149
144
150
145 def get_home_dir():
151 def get_home_dir():
146 """Return the closest possible equivalent to a 'home' directory.
152 """Return the closest possible equivalent to a 'home' directory.
147
153
148 * On POSIX, we try $HOME.
154 * On POSIX, we try $HOME.
149 * On Windows we try:
155 * On Windows we try:
150 - %HOMESHARE%
156 - %HOMESHARE%
151 - %HOMEDRIVE\%HOMEPATH%
157 - %HOMEDRIVE\%HOMEPATH%
152 - %USERPROFILE%
158 - %USERPROFILE%
153 - Registry hack for My Documents
159 - Registry hack for My Documents
154 - %HOME%: rare, but some people with unix-like setups may have defined it
160 - %HOME%: rare, but some people with unix-like setups may have defined it
155 * On Dos C:\
161 * On Dos C:\
156
162
157 Currently only Posix and NT are implemented, a HomeDirError exception is
163 Currently only Posix and NT are implemented, a HomeDirError exception is
158 raised for all other OSes.
164 raised for all other OSes.
159 """
165 """
160
166
161 isdir = os.path.isdir
167 isdir = os.path.isdir
162 env = os.environ
168 env = os.environ
163
169
164 # first, check py2exe distribution root directory for _ipython.
170 # first, check py2exe distribution root directory for _ipython.
165 # This overrides all. Normally does not exist.
171 # This overrides all. Normally does not exist.
166
172
167 if hasattr(sys, "frozen"): #Is frozen by py2exe
173 if hasattr(sys, "frozen"): #Is frozen by py2exe
168 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
174 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
169 root, rest = IPython.__file__.lower().split('library.zip')
175 root, rest = IPython.__file__.lower().split('library.zip')
170 else:
176 else:
171 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
177 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
172 root=os.path.abspath(root).rstrip('\\')
178 root=os.path.abspath(root).rstrip('\\')
173 if isdir(os.path.join(root, '_ipython')):
179 if isdir(os.path.join(root, '_ipython')):
174 os.environ["IPYKITROOT"] = root
180 os.environ["IPYKITROOT"] = root
175 return root.decode(fs_encoding)
181 return _cast_unicode(root, fs_encoding)
176
182
177 if os.name == 'posix':
183 if os.name == 'posix':
178 # Linux, Unix, AIX, OS X
184 # Linux, Unix, AIX, OS X
179 try:
185 try:
180 homedir = env['HOME']
186 homedir = env['HOME']
181 except KeyError:
187 except KeyError:
182 # Last-ditch attempt at finding a suitable $HOME, on systems where
188 # Last-ditch attempt at finding a suitable $HOME, on systems where
183 # it may not be defined in the environment but the system shell
189 # it may not be defined in the environment but the system shell
184 # still knows it - reported once as:
190 # still knows it - reported once as:
185 # https://github.com/ipython/ipython/issues/154
191 # https://github.com/ipython/ipython/issues/154
186 from subprocess import Popen, PIPE
192 from subprocess import Popen, PIPE
187 homedir = Popen('echo $HOME', shell=True,
193 homedir = Popen('echo $HOME', shell=True,
188 stdout=PIPE).communicate()[0].strip()
194 stdout=PIPE).communicate()[0].strip()
189 if homedir:
195 if homedir:
190 return homedir.decode(fs_encoding)
196 return _cast_unicode(homedir, fs_encoding)
191 else:
197 else:
192 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
198 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
193 else:
199 else:
194 return homedir.decode(fs_encoding)
200 return _cast_unicode(homedir, fs_encoding)
195 elif os.name == 'nt':
201 elif os.name == 'nt':
196 # Now for win9x, XP, Vista, 7?
202 # Now for win9x, XP, Vista, 7?
197 # For some strange reason all of these return 'nt' for os.name.
203 # For some strange reason all of these return 'nt' for os.name.
198 # First look for a network home directory. This will return the UNC
204 # First look for a network home directory. This will return the UNC
199 # path (\\server\\Users\%username%) not the mapped path (Z:\). This
205 # path (\\server\\Users\%username%) not the mapped path (Z:\). This
200 # is needed when running IPython on cluster where all paths have to
206 # is needed when running IPython on cluster where all paths have to
201 # be UNC.
207 # be UNC.
202 try:
208 try:
203 homedir = env['HOMESHARE']
209 homedir = env['HOMESHARE']
204 except KeyError:
210 except KeyError:
205 pass
211 pass
206 else:
212 else:
207 if isdir(homedir):
213 if isdir(homedir):
208 return homedir.decode(fs_encoding)
214 return _cast_unicode(homedir, fs_encoding)
209
215
210 # Now look for a local home directory
216 # Now look for a local home directory
211 try:
217 try:
212 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
218 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
213 except KeyError:
219 except KeyError:
214 pass
220 pass
215 else:
221 else:
216 if isdir(homedir):
222 if isdir(homedir):
217 return homedir.decode(fs_encoding)
223 return _cast_unicode(homedir, fs_encoding)
218
224
219 # Now the users profile directory
225 # Now the users profile directory
220 try:
226 try:
221 homedir = os.path.join(env['USERPROFILE'])
227 homedir = os.path.join(env['USERPROFILE'])
222 except KeyError:
228 except KeyError:
223 pass
229 pass
224 else:
230 else:
225 if isdir(homedir):
231 if isdir(homedir):
226 return homedir.decode(fs_encoding)
232 return _cast_unicode(homedir, fs_encoding)
227
233
228 # Use the registry to get the 'My Documents' folder.
234 # Use the registry to get the 'My Documents' folder.
229 try:
235 try:
230 import _winreg as wreg
236 import _winreg as wreg
231 key = wreg.OpenKey(
237 key = wreg.OpenKey(
232 wreg.HKEY_CURRENT_USER,
238 wreg.HKEY_CURRENT_USER,
233 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
239 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
234 )
240 )
235 homedir = wreg.QueryValueEx(key,'Personal')[0]
241 homedir = wreg.QueryValueEx(key,'Personal')[0]
236 key.Close()
242 key.Close()
237 except:
243 except:
238 pass
244 pass
239 else:
245 else:
240 if isdir(homedir):
246 if isdir(homedir):
241 return homedir.decode(fs_encoding)
247 return _cast_unicode(homedir, fs_encoding)
242
248
243 # A user with a lot of unix tools in win32 may have defined $HOME.
249 # A user with a lot of unix tools in win32 may have defined $HOME.
244 # Try this as a last ditch option.
250 # Try this as a last ditch option.
245 try:
251 try:
246 homedir = env['HOME']
252 homedir = env['HOME']
247 except KeyError:
253 except KeyError:
248 pass
254 pass
249 else:
255 else:
250 if isdir(homedir):
256 if isdir(homedir):
251 return homedir.decode(fs_encoding)
257 return _cast_unicode(homedir, fs_encoding)
252
258
253 # If all else fails, raise HomeDirError
259 # If all else fails, raise HomeDirError
254 raise HomeDirError('No valid home directory could be found')
260 raise HomeDirError('No valid home directory could be found')
255 elif os.name == 'dos':
261 elif os.name == 'dos':
256 # Desperate, may do absurd things in classic MacOS. May work under DOS.
262 # Desperate, may do absurd things in classic MacOS. May work under DOS.
257 return 'C:\\'.decode(fs_encoding)
263 return u'C:\\'
258 else:
264 else:
259 raise HomeDirError('No valid home directory could be found for your OS')
265 raise HomeDirError('No valid home directory could be found for your OS')
260
266
261 def get_xdg_dir():
267 def get_xdg_dir():
262 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
268 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
263
269
264 This is only for posix (Linux,Unix,OS X, etc) systems.
270 This is only for posix (Linux,Unix,OS X, etc) systems.
265 """
271 """
266
272
267 isdir = os.path.isdir
273 isdir = os.path.isdir
268 env = os.environ
274 env = os.environ
269
275
270 if os.name == 'posix':
276 if os.name == 'posix':
271 # Linux, Unix, AIX, OS X
277 # Linux, Unix, AIX, OS X
272 # use ~/.config if not set OR empty
278 # use ~/.config if not set OR empty
273 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
279 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
274 if xdg and isdir(xdg):
280 if xdg and isdir(xdg):
275 return xdg.decode(fs_encoding)
281 return _cast_unicode(xdg, fs_encoding)
276
282
277 return None
283 return None
278
284
279
285
280 def get_ipython_dir():
286 def get_ipython_dir():
281 """Get the IPython directory for this platform and user.
287 """Get the IPython directory for this platform and user.
282
288
283 This uses the logic in `get_home_dir` to find the home directory
289 This uses the logic in `get_home_dir` to find the home directory
284 and the adds .ipython to the end of the path.
290 and the adds .ipython to the end of the path.
285 """
291 """
286
292
287 env = os.environ
293 env = os.environ
288 pjoin = os.path.join
294 pjoin = os.path.join
289 exists = os.path.exists
295 exists = os.path.exists
290
296
291 ipdir_def = '.ipython'
297 ipdir_def = '.ipython'
292 xdg_def = 'ipython'
298 xdg_def = 'ipython'
293
299
294 home_dir = get_home_dir()
300 home_dir = get_home_dir()
295 xdg_dir = get_xdg_dir()
301 xdg_dir = get_xdg_dir()
296 # import pdb; pdb.set_trace() # dbg
302 # import pdb; pdb.set_trace() # dbg
297 ipdir = env.get('IPYTHON_DIR', env.get('IPYTHONDIR', None))
303 ipdir = env.get('IPYTHON_DIR', env.get('IPYTHONDIR', None))
298 if ipdir is None:
304 if ipdir is None:
299 # not set explicitly, use XDG_CONFIG_HOME or HOME
305 # not set explicitly, use XDG_CONFIG_HOME or HOME
300 home_ipdir = pjoin(home_dir, ipdir_def)
306 home_ipdir = pjoin(home_dir, ipdir_def)
301 if xdg_dir:
307 if xdg_dir:
302 # use XDG, as long as the user isn't already
308 # use XDG, as long as the user isn't already
303 # using $HOME/.ipython and *not* XDG/ipython
309 # using $HOME/.ipython and *not* XDG/ipython
304
310
305 xdg_ipdir = pjoin(xdg_dir, xdg_def)
311 xdg_ipdir = pjoin(xdg_dir, xdg_def)
306
312
307 if exists(xdg_ipdir) or not exists(home_ipdir):
313 if exists(xdg_ipdir) or not exists(home_ipdir):
308 ipdir = xdg_ipdir
314 ipdir = xdg_ipdir
309
315
310 if ipdir is None:
316 if ipdir is None:
311 # not using XDG
317 # not using XDG
312 ipdir = home_ipdir
318 ipdir = home_ipdir
313
319
314 return ipdir.decode(fs_encoding)
320 return _cast_unicode(ipdir, fs_encoding)
315
321
316
322
317 def get_ipython_package_dir():
323 def get_ipython_package_dir():
318 """Get the base directory where IPython itself is installed."""
324 """Get the base directory where IPython itself is installed."""
319 ipdir = os.path.dirname(IPython.__file__)
325 ipdir = os.path.dirname(IPython.__file__)
320 return ipdir.decode(fs_encoding)
326 return _cast_unicode(ipdir, fs_encoding)
321
327
322
328
323 def get_ipython_module_path(module_str):
329 def get_ipython_module_path(module_str):
324 """Find the path to an IPython module in this version of IPython.
330 """Find the path to an IPython module in this version of IPython.
325
331
326 This will always find the version of the module that is in this importable
332 This will always find the version of the module that is in this importable
327 IPython package. This will always return the path to the ``.py``
333 IPython package. This will always return the path to the ``.py``
328 version of the module.
334 version of the module.
329 """
335 """
330 if module_str == 'IPython':
336 if module_str == 'IPython':
331 return os.path.join(get_ipython_package_dir(), '__init__.py')
337 return os.path.join(get_ipython_package_dir(), '__init__.py')
332 mod = import_item(module_str)
338 mod = import_item(module_str)
333 the_path = mod.__file__.replace('.pyc', '.py')
339 the_path = mod.__file__.replace('.pyc', '.py')
334 the_path = the_path.replace('.pyo', '.py')
340 the_path = the_path.replace('.pyo', '.py')
335 return the_path.decode(fs_encoding)
341 return _cast_unicode(the_path, fs_encoding)
336
342
337
343
338 def expand_path(s):
344 def expand_path(s):
339 """Expand $VARS and ~names in a string, like a shell
345 """Expand $VARS and ~names in a string, like a shell
340
346
341 :Examples:
347 :Examples:
342
348
343 In [2]: os.environ['FOO']='test'
349 In [2]: os.environ['FOO']='test'
344
350
345 In [3]: expand_path('variable FOO is $FOO')
351 In [3]: expand_path('variable FOO is $FOO')
346 Out[3]: 'variable FOO is test'
352 Out[3]: 'variable FOO is test'
347 """
353 """
348 # This is a pretty subtle hack. When expand user is given a UNC path
354 # This is a pretty subtle hack. When expand user is given a UNC path
349 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
355 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
350 # the $ to get (\\server\share\%username%). I think it considered $
356 # the $ to get (\\server\share\%username%). I think it considered $
351 # alone an empty var. But, we need the $ to remains there (it indicates
357 # alone an empty var. But, we need the $ to remains there (it indicates
352 # a hidden share).
358 # a hidden share).
353 if os.name=='nt':
359 if os.name=='nt':
354 s = s.replace('$\\', 'IPYTHON_TEMP')
360 s = s.replace('$\\', 'IPYTHON_TEMP')
355 s = os.path.expandvars(os.path.expanduser(s))
361 s = os.path.expandvars(os.path.expanduser(s))
356 if os.name=='nt':
362 if os.name=='nt':
357 s = s.replace('IPYTHON_TEMP', '$\\')
363 s = s.replace('IPYTHON_TEMP', '$\\')
358 return s
364 return s
359
365
360
366
361 def target_outdated(target,deps):
367 def target_outdated(target,deps):
362 """Determine whether a target is out of date.
368 """Determine whether a target is out of date.
363
369
364 target_outdated(target,deps) -> 1/0
370 target_outdated(target,deps) -> 1/0
365
371
366 deps: list of filenames which MUST exist.
372 deps: list of filenames which MUST exist.
367 target: single filename which may or may not exist.
373 target: single filename which may or may not exist.
368
374
369 If target doesn't exist or is older than any file listed in deps, return
375 If target doesn't exist or is older than any file listed in deps, return
370 true, otherwise return false.
376 true, otherwise return false.
371 """
377 """
372 try:
378 try:
373 target_time = os.path.getmtime(target)
379 target_time = os.path.getmtime(target)
374 except os.error:
380 except os.error:
375 return 1
381 return 1
376 for dep in deps:
382 for dep in deps:
377 dep_time = os.path.getmtime(dep)
383 dep_time = os.path.getmtime(dep)
378 if dep_time > target_time:
384 if dep_time > target_time:
379 #print "For target",target,"Dep failed:",dep # dbg
385 #print "For target",target,"Dep failed:",dep # dbg
380 #print "times (dep,tar):",dep_time,target_time # dbg
386 #print "times (dep,tar):",dep_time,target_time # dbg
381 return 1
387 return 1
382 return 0
388 return 0
383
389
384
390
385 def target_update(target,deps,cmd):
391 def target_update(target,deps,cmd):
386 """Update a target with a given command given a list of dependencies.
392 """Update a target with a given command given a list of dependencies.
387
393
388 target_update(target,deps,cmd) -> runs cmd if target is outdated.
394 target_update(target,deps,cmd) -> runs cmd if target is outdated.
389
395
390 This is just a wrapper around target_outdated() which calls the given
396 This is just a wrapper around target_outdated() which calls the given
391 command if target is outdated."""
397 command if target is outdated."""
392
398
393 if target_outdated(target,deps):
399 if target_outdated(target,deps):
394 system(cmd)
400 system(cmd)
395
401
General Comments 0
You need to be logged in to leave comments. Login now