changeset 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
files examples/doctest.txt makeitso/makeitso.py makeitso/template.py
diffstat 3 files changed, 77 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/examples/doctest.txt	Mon Jan 10 14:39:21 2011 -0800
+++ b/examples/doctest.txt	Mon Jan 10 19:57:13 2011 -0800
@@ -1,7 +1,9 @@
 MakeItSo!
 =========
 
-Boilerplate:
+A filesystem templating system for rapid deploy of projects
+
+Boilerplate::
 
     >>> import makeitso
     >>> import os
@@ -15,22 +17,22 @@
     >>> template = makeitso.PolyTemplate([example], interactive=False)
     >>> template.missing()
     set(['name'])
-    >>> template.substitute(name='foo')
+    >>> template.substitute(output=None, name='foo')
     Hello foo
     
 Substitute to a buffer::
 
     >>> buffer = StringIO()
-    >>> template = makeitso.PolyTemplate([example], output=buffer, interactive=False)
-    >>> template.substitute(name='bar')
+    >>> template = makeitso.PolyTemplate([example], interactive=False)
+    >>> template.substitute(output=buffer, name='bar')
     >>> buffer.getvalue().strip()
     'Hello bar'
 
 Substitute to a file::
 
     >>> buffer = tempfile.mktemp()
-    >>> template = makeitso.PolyTemplate([example], output=buffer, interactive=False)
-    >>> template.substitute(name='fleem')
+    >>> template = makeitso.PolyTemplate([example], interactive=False)
+    >>> template.substitute(buffer, name='fleem')
     >>> file(buffer).read().strip()
     'Hello fleem'
     >>> os.remove(buffer)
@@ -39,10 +41,10 @@
 
     >>> exampledir = os.path.join(here, 'directory-example')
     >>> tempdir = tempfile.mkdtemp()
-    >>> template = makeitso.PolyTemplate([exampledir], output=tempdir, interactive=False)
+    >>> template = makeitso.PolyTemplate([exampledir], interactive=False)
     >>> sorted(template.missing())
     ['bar', 'foo', 'subdir']
-    >>> template.substitute(foo='It', bar='life', subdir='mysubdir')
+    >>> template.substitute(tempdir, foo='It', bar='life', subdir='mysubdir')
     >>> sorted(os.listdir(tempdir))
     ['foo.txt', 'mysubdir']
     >>> file(os.path.join(tempdir, 'foo.txt')).read().strip()
@@ -64,16 +66,16 @@
 
     >>> variables = dict([(i, i.title()) for i in variables])
     >>> try:
-    ...    template.substitute(**variables)
+    ...    template.substitute(output=None, **variables)
     ... except AssertionError, e:
     ...    pass
     >>> e
-    AssertionError('Must specify output ...
+    AssertionError()
 
 Provide an output::
 
-    >>> template = makeitso.PolyTemplate([example, exampledir], output=tempdir, interactive=False)
-    >>> template.substitute(**variables)
+    >>> template = makeitso.PolyTemplate([example, exampledir], interactive=False)
+    >>> template.substitute(tempdir, **variables)
     >>> sorted(os.listdir(tempdir))
     ['Subdir', 'example.txt', 'foo.txt']
     >>> shutil.rmtree(tempdir)
@@ -86,8 +88,8 @@
     ...    templates = ['example.txt']
     ...    vars = [Variable(name='name', default='bar')]
     >>> buffer = tempfile.mktemp()
-    >>> apitemplate = MyTemplate(output=buffer)
-    >>> apitemplate.substitute()
+    >>> apitemplate = MyTemplate(interactive=False)
+    >>> apitemplate.substitute(buffer)
     >>> file(buffer).read().strip()
     'Hello bar'
     >>> os.remove(buffer)
@@ -99,8 +101,8 @@
     >>> print >> f, '#!/bin/bash\necho foo'
     >>> f.close()
     >>> os.chmod(buffer, 0755)
-    >>> uritemplate = makeitso.URITemplate(example, output=buffer, interactive=False)
-    >>> uritemplate.substitute(name='bar')
+    >>> uritemplate = makeitso.URITemplate(example, interactive=False)
+    >>> uritemplate.substitute(buffer, name='bar')
     >>> ('%o' % os.stat(buffer).st_mode).endswith('755')
     True
     >>> os.remove(buffer)
--- a/makeitso/makeitso.py	Mon Jan 10 14:39:21 2011 -0800
+++ b/makeitso/makeitso.py	Mon Jan 10 19:57:13 2011 -0800
@@ -193,8 +193,7 @@
 class URITemplate(ContentTemplate):
     """template for a file or URL"""
 
-    def __init__(self, uri, output=None, interactive=True, variables=None):
-        self.output = output or sys.stdout        
+    def __init__(self, uri, interactive=True, variables=None):
         content = include(uri)
         
         # remove makeitso shebang if it has one
@@ -211,42 +210,47 @@
                                  interactive=interactive,
                                  variables=variables)
 
-    def substitute(self, **variables):
-        output = ContentTemplate.substitute(self, **variables)
-        f = self.output
-        
-        if isinstance(f, basestring):
-            path = f
-            if os.path.isdir(f):
+    def substitute(self, output=None, **variables):
+        content = ContentTemplate.substitute(self, **variables)
+        output = output or sys.stdout
+
+        if isinstance(output, basestring):
+            path = output
+            if os.path.isdir(output):
                 path = os.path.join(path, basename(self.name))
             f = file(path, 'w')
-            print >> f, output
+            print >> f, content
             f.close()
             try:
-                os.chmod(f, os.stat(self.name).st_mode)
+                os.chmod(path, os.stat(self.name).st_mode)
             except:
                 pass
         else:
-            print >> f, output
+            # file handler
+            print >> output, content
+
 
 class DirectoryTemplate(ContentTemplate):
     """template for a directory structure"""
     
-    def __init__(self, directory, output=None, interactive=True, variables=None):
+    def __init__(self, directory, interactive=True, variables=None):
         """
         - output : output directory; if None will render in place
         """
         assert os.path.isdir(directory)
         self.name = directory
         self.interactive = interactive
-        self.output = output
-        if output is not None:
-            if os.path.exists(output):
-                assert os.path.isdir(output), "%s: Must be a directory" % self.name
         self.defaults = ContentTemplate.defaults.copy()
         self.defaults.update(variables or {})
 
-
+    def check_output(self, output):
+        """
+        checks output for validity
+        """
+        assert output # must provide output
+        if os.path.exists(output):
+            assert os.path.isdir(output), "%s: Must be a directory" % self.name
+        
     def missing(self, **variables):
         vars = self.defaults.copy()
         vars.update(variables)
@@ -269,12 +273,15 @@
 
         return missing
 
-    def _substitute(self, **variables):
+    def substitute(self, output, **variables):
+        self.check_output(output)
+        vars = self.get_variables(**variables)
+        self.check_missing(vars)
+
         # TODO: do this with recursion instead of os.walk so that
         # per-directory control may be asserted
 
         # make output directory if necessary
-        output = self.output
         if output and not os.path.exists(output):
             os.makedirs(output)
             
@@ -284,7 +291,7 @@
             for d in dirnames:
                 path = os.path.join(dirname, d)
                 interpolated = ContentTemplate(path).substitute(**variables)
-                target = os.path.join(self.output, interpolated.split(self.name, 1)[-1].strip(os.path.sep))
+                target = os.path.join(output, interpolated.split(self.name, 1)[-1].strip(os.path.sep))
                 
                 if os.path.exists(target):
                     # ensure its a directory
@@ -297,33 +304,30 @@
             for filename in filenames:
                 path = os.path.join(dirname, filename)
                 interpolated = ContentTemplate(path).substitute(**variables)
-                target = os.path.join(self.output, interpolated.split(self.name, 1)[-1].strip(os.path.sep))
+                target = os.path.join(output, interpolated.split(self.name, 1)[-1].strip(os.path.sep))
                 
                 if os.path.exists(target):
                     # ensure its a directory
                     # TODO: check this first before interpolation is in progress
                     assert os.path.isfile(target), "Can't substitute a file on top of a directory"
-                template = URITemplate(path, output=target, interactive=False)
-                template.substitute(**variables)
+                template = URITemplate(path, interactive=False)
+                template.substitute(target, **variables)
 
 
 class PolyTemplate(ContentTemplate):
     """template for several files/directories"""
 
-    def __init__(self, templates, output=None, interactive=True, variables=None):
-
-        assert templates, "No templates given!"
+    def __init__(self, templates, interactive=True, variables=None):
 
         self.interactive = interactive
         self._templates = templates[:]
         self.templates = []
-        self.output = output
         for template in templates:
             # TODO: check if the template is a [e.g] PasteScript.template entry point
             if os.path.isdir(template):
-                self.templates.append(DirectoryTemplate(template, interactive=self.interactive, output=output, variables=variables))
+                self.templates.append(DirectoryTemplate(template, interactive=self.interactive, variables=variables))
             else:
-                self.templates.append(URITemplate(template, interactive=self.interactive, output=output, variables=variables))
+                self.templates.append(URITemplate(template, interactive=self.interactive, variables=variables))
 
     def missing(self, **variables):
         vars = variables.copy()
@@ -334,19 +338,29 @@
             vars.update(dict([(i, '') for i in missed]))
         return missing
 
-    def _substitute(self, **variables):
+    def check_output(self, output):
+        if output and isinstance(output, basestring) and os.path.exists(output) and len(self.templates) > 1:
+            assert os.path.isdir(output), "Must specify a directory for multiple templates"
+        for template in self.templates:
+            if hasattr(template, 'check_output'):
+                template.check_output(output)
+
+    def substitute(self, output=None, **variables):
 
         # determine where the hell to put these things
-        if self.output is None:
-            dirs = [i for i in self._templates if os.path.isdir(i)]
-            if not ((len(dirs) == 0) or len(dirs) == len(self.templates)):
-                raise AssertionError("Must specify output when mixing directories and URIs")
-        
-        # TODO: check for missing
-        if len(self.templates) > 1 and not os.path.exists(self.output):
-            os.makedirs(self.output)
+        self.check_output(output)
+
+        # get the variables
+        vars = self.get_variables(**variables)
+        self.check_missing(vars)
+
+        # make the output directory
+        if output and len(self.templates) > 1 and not os.path.exists(output):
+            os.makedirs(output)
+
+        # do the substitution
         for template in self.templates:
-            template.substitute(**variables)
+            template.substitute(output, **variables)
         
 ### command line interface
 
@@ -423,11 +437,11 @@
     # get the content
     if args:
         template = PolyTemplate(templates=args,
-                                output=options.output,
                                 variables=variables)
+        template.substitute(output=options.output)
     else:
         template = ContentTemplate(sys.stdin.read(), variables=variables)
-    template.substitute()
+        print template.substitute()
 
     # cleanup
     cleanup()
--- a/makeitso/template.py	Mon Jan 10 14:39:21 2011 -0800
+++ b/makeitso/template.py	Mon Jan 10 19:57:13 2011 -0800
@@ -151,7 +151,7 @@
     def pre(self, variables):
         """do stuff before interpolation"""
 
-    def substitute(self, **variables):
+    def substitute(self, output, **variables):
         """do the substitution"""
         
         vars = self.get_variables(**variables)
@@ -160,10 +160,10 @@
 
         # do the substitution
         template = PolyTemplate(self._templates,
-                                output=self.output,
                                 interactive=self.interactive,
                                 variables=vars)
-        template.substitute()
+        template.check_output(output)
+        template.substitute(output)
                      
         self.post(vars)