Permalink
Browse files

Get rid of all uses of Mako in pants.

Mako is platform-dependent, leading to deployment headaches.
Instead we now use mustache, whose python bindings (pystache)
are pure python.
  • Loading branch information...
1 parent 49d7950 commit e28afe768eed4d1b50d7817e1de2eb2b9d0b46bd Benjy committed Dec 12, 2012
Showing with 295 additions and 265 deletions.
  1. +1 −1 3rdparty/python/BUILD
  2. BIN 3rdparty/python/pystache-0.5.3-py2.6.egg
  3. +2 −1 pants
  4. +2 −2 src/python/twitter/pants/BUILD
  5. +20 −2 src/python/twitter/pants/ant/lib.py
  6. +21 −18 src/python/twitter/pants/base/generator.py
  7. +1 −1 src/python/twitter/pants/pants_doc/doc_builder.py
  8. +1 −1 src/python/twitter/pants/pants_doc/templates/{doc.mk → doc.mustache}
  9. +18 −18 src/python/twitter/pants/tasks/eclipse/templates/{classpath-3.7.mk → classpath-3.7.mustache}
  10. +3 −3 ...ython/twitter/pants/tasks/eclipse/templates/{debug-launcher-3.7.mk → debug-launcher-3.7.mustache}
  11. +3 −3 src/python/twitter/pants/tasks/eclipse/templates/{factorypath-3.7.mk → factorypath-3.7.mustache}
  12. +20 −19 src/python/twitter/pants/tasks/eclipse/templates/{project-3.7.mk → project-3.7.mustache}
  13. +11 −10 src/python/twitter/pants/tasks/eclipse/templates/{pydevproject-3.7.mk → pydevproject-3.7.mustache}
  14. +20 −14 src/python/twitter/pants/tasks/eclipse_gen.py
  15. +1 −1 src/python/twitter/pants/tasks/ide_gen.py
  16. +41 −40 src/python/twitter/pants/tasks/idea/templates/{module-11.mk → module-11.mustache}
  17. +25 −25 src/python/twitter/pants/tasks/idea/templates/{project-11.mk → project-11.mustache}
  18. +5 −2 src/python/twitter/pants/tasks/idea_gen.py
  19. +3 −3 src/python/twitter/pants/tasks/ivy_resolve.py
  20. +60 −64 src/python/twitter/pants/tasks/ivy_resolve/{ivy.mk → ivy.mustache}
  21. +8 −8 src/python/twitter/pants/tasks/jar_publish.py
  22. +11 −11 src/python/twitter/pants/tasks/jar_publish/{ivysettings.mk → ivysettings.mustache}
  23. +18 −18 src/python/twitter/pants/tasks/jar_publish/{pom.mk → pom.mustache}
View
@@ -147,7 +147,7 @@ python_library(
python_library(
name = 'pystache',
- dependencies = [egg('pystache-0.3.1-py2.6.egg')])
+ dependencies = [egg('pystache-0.5.3-py2.6.egg')])
python_library(
name = 'lxml',
Binary file not shown.
View
3 pants
@@ -22,11 +22,12 @@ PANTS_EXE=$MY_DIR/src/python/twitter/pants/bin/pants_exe.py
MAKO_EGG=$MY_DIR/3rdparty/python/Mako-0.4.0-py2.6.egg
MARKDOWN_EGG=$MY_DIR/3rdparty/python/Markdown-2.1.1-py2.6.egg
PYGMENTS_EGG=$MY_DIR/3rdparty/python/Pygments-1.4-py2.6.egg
+PYSTACHE_EGG=$MY_DIR/3rdparty/python/pystache-0.5.3-py2.6.egg
PYTHON_DAEMON_EGG=$MY_DIR/3rdparty/python/python_daemon-1.6-py2.6.egg
function run_pants_bare() {
source $VIRTUAL_PYTHON/bin/activate
- PYTHONPATH=$MAKO_EGG:$MARKDOWN_EGG:$PYGMENTS_EGG:$PYTHON_DAEMON_EGG:$MY_DIR/src/python python $PANTS_EXE "$@"
+ PYTHONPATH=$MAKO_EGG:$MARKDOWN_EGG:$PYGMENTS_EGG:$PYSTACHE_EGG:$PYTHON_DAEMON_EGG:$MY_DIR/src/python python $PANTS_EXE "$@"
deactivate
}
@@ -27,11 +27,11 @@ python_library(
name = 'pants-deps',
dependencies = [
python_requirement('elementtree'),
- python_requirement('mako'),
+ python_requirement('mako'), # TODO: Remove after getting rid of the doc command.
python_requirement('markdown'),
- python_requirement('psutil'),
python_requirement('pygments'),
python_requirement('pylint', version_filter=pylint_build_filter),
+ python_requirement('pystache'),
python_requirement('pytest'),
python_requirement('python_daemon'),
]
@@ -22,9 +22,10 @@
import subprocess
import traceback
+from mako.template import Template
+
from twitter.pants import has_jvm_targets, is_jvm
from twitter.pants.ant import bang
-from twitter.pants.base.generator import Generator
from twitter.pants.base.builder import Builder
from twitter.pants.targets import (
JarDependency,
@@ -53,7 +54,7 @@ def generate_ivy(cls, root_dir, output_filename, target):
def _generate(cls, root_dir, template, template_data, output_filename):
with open(output_filename, 'w') as output:
template_path = os.path.join(_TEMPLATE_BASEDIR, '%s.mk' % template)
- generator = Generator(pkgutil.get_data(__name__, template_path),
+ generator = MakoGenerator(pkgutil.get_data(__name__, template_path),
root_dir = root_dir, lib = template_data)
generator.write(output)
@@ -196,3 +197,20 @@ def _resolve_targets(self, targets, name = None):
return bang.extract_target(targets, name)
else:
return foil
+
+class MakoGenerator(object):
+ """Generates pants intermediary output files using a configured mako template."""
+
+ _module_directory = '/tmp/pants-%s' % os.environ['USER']
+
+ def __init__(self, template_text, **template_data):
+ self._template = Template(text = template_text,
+ module_directory = MakoGenerator._module_directory)
+ self.template_data = template_data
+
+ def write(self, stream):
+ """Applies the template to the template data and writes the result to the given file-like
+ stream."""
+
+ stream.write(self._template.render(**self.template_data))
+
@@ -16,24 +16,30 @@
from __future__ import print_function
-import sys
-
-class PantsBootstrapError(ImportError):
- pass
+import pprint
+import pystache
-try:
- from mako.template import Template
-except ImportError:
- raise PantsBootstrapError("Could not properly bootstrap Pants because Mako is missing!")
-import os
-import pprint
+def _expand(map):
+ # Add has_foo for each foo in the map that evaluates to true.
+ # Mustache needs this, especially in cases where foo is a list.
+ # Note: if the original map contains has_foo, it will take precedence over our synthetic has_foo.
+ def set_to_map(x):
+ # Pystache can't handle sets, so we convert to maps of key->True.
+ if isinstance(x, set):
+ return dict([(k, True) for k in x])
+ else:
+ return x
+ items = [(key, set_to_map(val)) for (key, val) in map.items()]
+ ret = dict([('has_' + key, True) for (key, val) in items if val])
+ ret.update(dict(items))
+ return ret
class TemplateData(dict):
- """Encapsulates data for a mako template as a property-addressable read-only map-like struct."""
+ """Encapsulates data for a mustache template as a property-addressable read-only map-like struct."""
def __init__(self, **kwargs):
- dict.__init__(self, kwargs)
+ dict.__init__(self, _expand(kwargs))
def extend(self, **kwargs):
"""Returns a new TemplateData with this template's data overlayed by the key value pairs
@@ -56,17 +62,14 @@ def __str__(self):
return 'TemplateData(%s)' % pprint.pformat(self)
class Generator(object):
- """Generates pants intermediary output files using a configured mako template."""
-
- _module_directory = '/tmp/pants-%s' % os.environ['USER']
+ """Generates pants intermediary output files using a configured mustache template."""
def __init__(self, template_text, **template_data):
- self._template = Template(text = template_text,
- module_directory = Generator._module_directory)
+ self._template = pystache.parse(unicode(template_text))
self.template_data = template_data
def write(self, stream):
"""Applies the template to the template data and writes the result to the given file-like
stream."""
+ stream.write(pystache.render(self._template, self.template_data))
- stream.write(self._template.render(**self.template_data))
@@ -38,7 +38,7 @@ def __init__(self, root_dir):
self.root_dir = root_dir
def build(self, targets, _):
- template_path = os.path.join(_TEMPLATE_BASEDIR, 'doc.mk')
+ template_path = os.path.join(_TEMPLATE_BASEDIR, 'doc.mustache')
template = pkgutil.get_data(__name__, template_path)
for target in targets:
assert is_doc(target), 'DocBuilder can only build DocTargets, given %s' % str(target)
@@ -1,4 +1,4 @@
<html>
<body>
-${text}
+{{text}}
</body>
@@ -20,32 +20,32 @@ limitations under the License.
<!-- generated by pants! -->
<classpath>
- % if classpath.has_scala:
+ {{#classpath.has_scala}}
<classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
- % endif
+ {{/classpath.has_scala}}
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- % for sourcepath in classpath.sourcepaths:
+ {{#classpath.sourcepaths}}
<classpathentry kind="src"
- path="${sourcepath.base}"
- % if sourcepath.includes:
- including="${'|'.join(sourcepath.includes)}"
- % endif
- % if sourcepath.excludes:
- excluding="${'|'.join(sourcepath.excludes)}"
- % endif
+ path="{{base}}"
+ {{#joined_includes}}
+ including="{{.}}"
+ {{/joined_includes}}
+ {{#joined_excludes}}
+ excluding="{{.}}"
+ {{/joined_excludes}}
/>
- % endfor
+ {{/classpath.sourcepaths}}
- % for jar, source_jar in classpath.libs:
+ {{#classpath.libs}}
<classpathentry kind="lib"
- path="${jar}"
- % if source_jar:
- sourcepath="${source_jar}"
- % endif
+ path="{{jar}}"
+ {{#source_jar}}
+ sourcepath="{{.}}"
+ {{/source_jar}}
/>
- % endfor
+ {{/classpath.libs}}
- <classpathentry kind="output" path="${classpath.outdir}"/>
+ <classpathentry kind="output" path="{{classpath.outdir}}"/>
</classpath>
@@ -21,7 +21,7 @@ limitations under the License.
<!-- generated by pants! -->
<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
- <listEntry value="/${project.name}"/>
+ <listEntry value="/{{project.name}}"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
@@ -32,9 +32,9 @@ limitations under the License.
<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
<mapEntry key="hostname" value="localhost"/>
- <mapEntry key="port" value="${project.debug_port}"/>
+ <mapEntry key="port" value="{{project.debug_port}}"/>
</mapAttribute>
- <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="${project.name}"/>
+ <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="{{project.name}}"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID"
value="org.eclipse.jdt.launching.socketAttachConnector"/>
</launchConfiguration>
@@ -20,9 +20,9 @@ limitations under the License.
<!-- generated by pants! -->
<factorypath>
- % for jarpath in factorypath.jarpaths:
- <factorypathentry kind="WKSPJAR" id="/${factorypath.project_name}/${jarpath}"
+ {{#factorypath.jarpaths}}
+ <factorypathentry kind="WKSPJAR" id="/{{factorypath.project_name}}/{{.}}"
enabled="true"
runInBatchMode="false"/>
- % endfor
+ {{/factorypath.jarpaths}}
</factorypath>
@@ -20,55 +20,56 @@ limitations under the License.
<!-- generated by pants! -->
<projectDescription>
- <name>${project.name}</name>
+ <name>{{project.name}}</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
- ## For whatever reason in a mixed scala/java project, the only jvm builder must be the scala
- ## builder circa eclipse 3.6
- % if project.has_scala:
+ {{! For whatever reason in a mixed scala/java project, the only jvm builder must be the scala
+ builder circa eclipse 3.6}}
+ {{#project.has_scala}}
<buildCommand>
<name>org.scala-ide.sdt.core.scalabuilder</name>
<arguments>
</arguments>
</buildCommand>
- % else:
+ {{/project.has_scala}}
+ {{^project.has_scala}}
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
- % endif
- % if project.has_python:
+ {{/project.has_scala}}
+ {{#project.has_python}}
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
- % endif
+ {{/project.has_python}}
</buildSpec>
<natures>
- % if project.has_scala:
+ {{#project.has_scala}}
<nature>org.scala-ide.sdt.core.scalanature</nature>
- % endif
+ {{/project.has_scala}}
<nature>org.eclipse.jdt.core.javanature</nature>
- % if project.has_python:
+ {{#project.has_python}}
<nature>org.python.pydev.pythonNature</nature>
- % endif
+ {{/project.has_python}}
</natures>
- % if project.source_bases:
+ {{#project.has_source_bases}}
<linkedResources>
- % for source_base, id in project.source_bases:
+ {{#project.source_bases}}
<link>
- <name>${id}</name>
- ## TODO(John Sirois): What does 2 mean? - find out and document.
+ <name>{{id}}</name>
+ {{! TODO(John Sirois): What does 2 mean? - find out and document.}}
<type>2</type>
- <location>${source_base}</location>
+ <location>{{path}}</location>
</link>
- % endfor
+ {{/project.source_bases}}
</linkedResources>
- % endif
+ {{/project.has_source_bases}}
</projectDescription>
@@ -21,18 +21,19 @@ limitations under the License.
<!-- generated by pants! -->
<pydev_project>
- ## TODO(John Sirois): support python project setups with interpreter of choice
+ {{! TODO(John Sirois): support python project setups with interpreter of choice.}}
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
- % for sourcepath in project.pythonpaths:
- % if sourcepath.includes:
- % for include in sourcepath.includes:
- <path>/${project.name}/${sourcepath.base}/${include}</path>
- % endfor
- % else:
- <path>/${project.name}/${sourcepath.base}</path>
- % endif
- % endfor
+ {{#project.pythonpaths}}
+ {{#has_includes}}
+ {{#includes}}
+ <path>/{{project.name}}/{{base}}/{{.}}</path>
+ {{/includes}}
+ {{/has_includes}}
+ {{^has_includes}}
+ <path>/{{project.name}}/{{base}}</path>
+ {{/has_includes}}
+ {{/project.pythonpaths}}
</pydev_pathproperty>
</pydev_project>
Oops, something went wrong.

0 comments on commit e28afe7

Please sign in to comment.