Mercurial > hg > MakeItSo
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__': |
