comparison makeitso/makeitso.py @ 88:712a6d358083

fixed output broke other things
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 10 Jan 2011 19:57:13 -0800
parents 3571417ef92e
children e055447376ab
comparison
equal deleted inserted replaced
87:3571417ef92e 88:712a6d358083
191 191
192 192
193 class URITemplate(ContentTemplate): 193 class URITemplate(ContentTemplate):
194 """template for a file or URL""" 194 """template for a file or URL"""
195 195
196 def __init__(self, uri, output=None, interactive=True, variables=None): 196 def __init__(self, uri, interactive=True, variables=None):
197 self.output = output or sys.stdout
198 content = include(uri) 197 content = include(uri)
199 198
200 # remove makeitso shebang if it has one 199 # remove makeitso shebang if it has one
201 if shebang_re.match(content): 200 if shebang_re.match(content):
202 content = os.linesep.join(content.splitlines()[1:]) 201 content = os.linesep.join(content.splitlines()[1:])
209 208
210 ContentTemplate.__init__(self, content, name=uri, 209 ContentTemplate.__init__(self, content, name=uri,
211 interactive=interactive, 210 interactive=interactive,
212 variables=variables) 211 variables=variables)
213 212
214 def substitute(self, **variables): 213 def substitute(self, output=None, **variables):
215 output = ContentTemplate.substitute(self, **variables) 214 content = ContentTemplate.substitute(self, **variables)
216 f = self.output 215 output = output or sys.stdout
217 216
218 if isinstance(f, basestring): 217 if isinstance(output, basestring):
219 path = f 218 path = output
220 if os.path.isdir(f): 219 if os.path.isdir(output):
221 path = os.path.join(path, basename(self.name)) 220 path = os.path.join(path, basename(self.name))
222 f = file(path, 'w') 221 f = file(path, 'w')
223 print >> f, output 222 print >> f, content
224 f.close() 223 f.close()
225 try: 224 try:
226 os.chmod(f, os.stat(self.name).st_mode) 225 os.chmod(path, os.stat(self.name).st_mode)
227 except: 226 except:
228 pass 227 pass
229 else: 228 else:
230 print >> f, output 229 # file handler
230 print >> output, content
231
231 232
232 class DirectoryTemplate(ContentTemplate): 233 class DirectoryTemplate(ContentTemplate):
233 """template for a directory structure""" 234 """template for a directory structure"""
234 235
235 def __init__(self, directory, output=None, interactive=True, variables=None): 236 def __init__(self, directory, interactive=True, variables=None):
236 """ 237 """
237 - output : output directory; if None will render in place 238 - output : output directory; if None will render in place
238 """ 239 """
239 assert os.path.isdir(directory) 240 assert os.path.isdir(directory)
240 self.name = directory 241 self.name = directory
241 self.interactive = interactive 242 self.interactive = interactive
242 self.output = output
243 if output is not None:
244 if os.path.exists(output):
245 assert os.path.isdir(output), "%s: Must be a directory" % self.name
246 self.defaults = ContentTemplate.defaults.copy() 243 self.defaults = ContentTemplate.defaults.copy()
247 self.defaults.update(variables or {}) 244 self.defaults.update(variables or {})
248 245
249 246 def check_output(self, output):
247 """
248 checks output for validity
249 """
250 assert output # must provide output
251 if os.path.exists(output):
252 assert os.path.isdir(output), "%s: Must be a directory" % self.name
253
250 def missing(self, **variables): 254 def missing(self, **variables):
251 vars = self.defaults.copy() 255 vars = self.defaults.copy()
252 vars.update(variables) 256 vars.update(variables)
253 missing = set([]) 257 missing = set([])
254 for dirpath, dirnames, filenames in os.walk(self.name): 258 for dirpath, dirnames, filenames in os.walk(self.name):
267 missing.update(missed) 271 missing.update(missed)
268 variables.update(dict([(i, '') for i in missed])) 272 variables.update(dict([(i, '') for i in missed]))
269 273
270 return missing 274 return missing
271 275
272 def _substitute(self, **variables): 276 def substitute(self, output, **variables):
277 self.check_output(output)
278 vars = self.get_variables(**variables)
279 self.check_missing(vars)
280
273 # TODO: do this with recursion instead of os.walk so that 281 # TODO: do this with recursion instead of os.walk so that
274 # per-directory control may be asserted 282 # per-directory control may be asserted
275 283
276 # make output directory if necessary 284 # make output directory if necessary
277 output = self.output
278 if output and not os.path.exists(output): 285 if output and not os.path.exists(output):
279 os.makedirs(output) 286 os.makedirs(output)
280 287
281 for dirname, dirnames, filenames in os.walk(self.name): 288 for dirname, dirnames, filenames in os.walk(self.name):
282 289
283 # interpolate directory names 290 # interpolate directory names
284 for d in dirnames: 291 for d in dirnames:
285 path = os.path.join(dirname, d) 292 path = os.path.join(dirname, d)
286 interpolated = ContentTemplate(path).substitute(**variables) 293 interpolated = ContentTemplate(path).substitute(**variables)
287 target = os.path.join(self.output, interpolated.split(self.name, 1)[-1].strip(os.path.sep)) 294 target = os.path.join(output, interpolated.split(self.name, 1)[-1].strip(os.path.sep))
288 295
289 if os.path.exists(target): 296 if os.path.exists(target):
290 # ensure its a directory 297 # ensure its a directory
291 # TODO: check this first before interpolation is in progress 298 # TODO: check this first before interpolation is in progress
292 assert os.path.isdir(target), "Can't substitute a directory on top of the file" 299 assert os.path.isdir(target), "Can't substitute a directory on top of the file"
295 302
296 # interpolate files 303 # interpolate files
297 for filename in filenames: 304 for filename in filenames:
298 path = os.path.join(dirname, filename) 305 path = os.path.join(dirname, filename)
299 interpolated = ContentTemplate(path).substitute(**variables) 306 interpolated = ContentTemplate(path).substitute(**variables)
300 target = os.path.join(self.output, interpolated.split(self.name, 1)[-1].strip(os.path.sep)) 307 target = os.path.join(output, interpolated.split(self.name, 1)[-1].strip(os.path.sep))
301 308
302 if os.path.exists(target): 309 if os.path.exists(target):
303 # ensure its a directory 310 # ensure its a directory
304 # TODO: check this first before interpolation is in progress 311 # TODO: check this first before interpolation is in progress
305 assert os.path.isfile(target), "Can't substitute a file on top of a directory" 312 assert os.path.isfile(target), "Can't substitute a file on top of a directory"
306 template = URITemplate(path, output=target, interactive=False) 313 template = URITemplate(path, interactive=False)
307 template.substitute(**variables) 314 template.substitute(target, **variables)
308 315
309 316
310 class PolyTemplate(ContentTemplate): 317 class PolyTemplate(ContentTemplate):
311 """template for several files/directories""" 318 """template for several files/directories"""
312 319
313 def __init__(self, templates, output=None, interactive=True, variables=None): 320 def __init__(self, templates, interactive=True, variables=None):
314
315 assert templates, "No templates given!"
316 321
317 self.interactive = interactive 322 self.interactive = interactive
318 self._templates = templates[:] 323 self._templates = templates[:]
319 self.templates = [] 324 self.templates = []
320 self.output = output
321 for template in templates: 325 for template in templates:
322 # TODO: check if the template is a [e.g] PasteScript.template entry point 326 # TODO: check if the template is a [e.g] PasteScript.template entry point
323 if os.path.isdir(template): 327 if os.path.isdir(template):
324 self.templates.append(DirectoryTemplate(template, interactive=self.interactive, output=output, variables=variables)) 328 self.templates.append(DirectoryTemplate(template, interactive=self.interactive, variables=variables))
325 else: 329 else:
326 self.templates.append(URITemplate(template, interactive=self.interactive, output=output, variables=variables)) 330 self.templates.append(URITemplate(template, interactive=self.interactive, variables=variables))
327 331
328 def missing(self, **variables): 332 def missing(self, **variables):
329 vars = variables.copy() 333 vars = variables.copy()
330 missing = set([]) 334 missing = set([])
331 for template in self.templates: 335 for template in self.templates:
332 missed = template.missing(**vars) 336 missed = template.missing(**vars)
333 missing.update(missed) 337 missing.update(missed)
334 vars.update(dict([(i, '') for i in missed])) 338 vars.update(dict([(i, '') for i in missed]))
335 return missing 339 return missing
336 340
337 def _substitute(self, **variables): 341 def check_output(self, output):
342 if output and isinstance(output, basestring) and os.path.exists(output) and len(self.templates) > 1:
343 assert os.path.isdir(output), "Must specify a directory for multiple templates"
344 for template in self.templates:
345 if hasattr(template, 'check_output'):
346 template.check_output(output)
347
348 def substitute(self, output=None, **variables):
338 349
339 # determine where the hell to put these things 350 # determine where the hell to put these things
340 if self.output is None: 351 self.check_output(output)
341 dirs = [i for i in self._templates if os.path.isdir(i)] 352
342 if not ((len(dirs) == 0) or len(dirs) == len(self.templates)): 353 # get the variables
343 raise AssertionError("Must specify output when mixing directories and URIs") 354 vars = self.get_variables(**variables)
344 355 self.check_missing(vars)
345 # TODO: check for missing 356
346 if len(self.templates) > 1 and not os.path.exists(self.output): 357 # make the output directory
347 os.makedirs(self.output) 358 if output and len(self.templates) > 1 and not os.path.exists(output):
359 os.makedirs(output)
360
361 # do the substitution
348 for template in self.templates: 362 for template in self.templates:
349 template.substitute(**variables) 363 template.substitute(output, **variables)
350 364
351 ### command line interface 365 ### command line interface
352 366
353 def invocation(url, **variables): 367 def invocation(url, **variables):
354 """returns a string appropriate for TTW invocation""" 368 """returns a string appropriate for TTW invocation"""
421 return 435 return
422 436
423 # get the content 437 # get the content
424 if args: 438 if args:
425 template = PolyTemplate(templates=args, 439 template = PolyTemplate(templates=args,
426 output=options.output,
427 variables=variables) 440 variables=variables)
441 template.substitute(output=options.output)
428 else: 442 else:
429 template = ContentTemplate(sys.stdin.read(), variables=variables) 443 template = ContentTemplate(sys.stdin.read(), variables=variables)
430 template.substitute() 444 print template.substitute()
431 445
432 # cleanup 446 # cleanup
433 cleanup() 447 cleanup()
434 448
435 if __name__ == '__main__': 449 if __name__ == '__main__':