| @@ -1,7 +1,4 @@ | |||||
| Django==1.2.3 | |||||
| Genshi==0.6 | |||||
| Jinja2==2.5.5 | Jinja2==2.5.5 | ||||
| Mako==0.3.6 | |||||
| Markdown==2.0.3 | Markdown==2.0.3 | ||||
| MarkupSafe==0.11 | MarkupSafe==0.11 | ||||
| PyYAML==3.09 | PyYAML==3.09 | ||||
| @@ -3,15 +3,17 @@ | |||||
| The command line interface for hyde. | The command line interface for hyde. | ||||
| """ | """ | ||||
| import argparse | import argparse | ||||
| from engine import init, gen, serve | |||||
| from version import __version__ | from version import __version__ | ||||
| from engine import init, gen, serve | |||||
| def main(): | def main(): | ||||
| """ | """ | ||||
| The main function called by hyde executable | The main function called by hyde executable | ||||
| """ | """ | ||||
| parser = argparse.ArgumentParser(description='hyde - A Python Static Website Generator', | |||||
| import sys | |||||
| print sys.argv | |||||
| parser = argparse.ArgumentParser(description='hyde - a python static website generator', | |||||
| epilog='Use %(prog)s {command} -h to get help on individual commands') | epilog='Use %(prog)s {command} -h to get help on individual commands') | ||||
| parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + __version__) | parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + __version__) | ||||
| parser.add_argument('-s', '--sitepath', action='store', default='.', help="Location of the hyde site") | parser.add_argument('-s', '--sitepath', action='store', default='.', help="Location of the hyde site") | ||||
| @@ -24,4 +26,5 @@ def main(): | |||||
| init_command.add_argument('-f', '--force', action='store_true', default=False, dest='force', | init_command.add_argument('-f', '--force', action='store_true', default=False, dest='force', | ||||
| help='Overwrite the current site if it exists') | help='Overwrite the current site if it exists') | ||||
| args = parser.parse_args() | args = parser.parse_args() | ||||
| args.run(args) | |||||
| args.run(args) | |||||
| @@ -0,0 +1,95 @@ | |||||
| # -*- coding: utf-8 -*- | |||||
| """ | |||||
| A nice declarative interface for Argument parser | |||||
| """ | |||||
| from argparse import ArgumentParser, Namespace | |||||
| from collections import namedtuple | |||||
| __all__ = [ | |||||
| 'command', | |||||
| 'param', | |||||
| 'Application' | |||||
| ] | |||||
| class CommandLine(type): | |||||
| """ | |||||
| Meta class that enables declarative command definitions | |||||
| """ | |||||
| def __new__(cls, name, bases, attrs): | |||||
| instance = super(CommandLine, cls).__new__(cls, name, bases, attrs) | |||||
| subcommands = [] | |||||
| main_command = None | |||||
| for name, member in attrs.iteritems(): | |||||
| if hasattr(member, "command"): | |||||
| main_command = member | |||||
| # else if member.params: | |||||
| # subcommands.append(member) | |||||
| parser = None | |||||
| if main_command: | |||||
| parser = ArgumentParser(*main_command.command.args, **main_command.command.kwargs) | |||||
| for param in main_command.params: | |||||
| parser.add_argument(*param.args, **param.kwargs) | |||||
| # subparsers = None | |||||
| # if subcommands.length: | |||||
| # subparsers = parser.add_subparsers() | |||||
| # | |||||
| # for command in subcommands: | |||||
| # | |||||
| # for param in main_command.params: | |||||
| # parser.add_argument(*param.args, **param.kwargs) | |||||
| instance.parser = parser | |||||
| instance.main = main_command | |||||
| return instance | |||||
| values = namedtuple('__meta_values', 'args, kwargs') | |||||
| class metarator(object): | |||||
| """ | |||||
| A generic decorator that tags the decorated method with | |||||
| the passed in arguments for meta classes to process them. | |||||
| """ | |||||
| def __init__(self, *args, **kwargs): | |||||
| self.values = values._make((args, kwargs)) | |||||
| def metarate(self, f, name='values'): | |||||
| setattr(f, name, self.values) | |||||
| return f | |||||
| def __call__(self, f): | |||||
| return self.metarate(f) | |||||
| class command(metarator): | |||||
| """ | |||||
| Used to decorate the main entry point | |||||
| """ | |||||
| def __call__(self, f): | |||||
| return self.metarate(f, name='command') | |||||
| class param(metarator): | |||||
| """ | |||||
| Use this decorator instead of `ArgumentParser.add_argument`. | |||||
| """ | |||||
| def __call__(self, f): | |||||
| f.params = f.params if hasattr(f, 'params') else [] | |||||
| f.params.append(self.values) | |||||
| return f | |||||
| class Application(object): | |||||
| """ | |||||
| Bare bones base class for command line applications. Hides the | |||||
| meta programming complexities. | |||||
| """ | |||||
| __metaclass__ = CommandLine | |||||
| def parse(self, argv): | |||||
| return self.parser.parse_args(argv) | |||||
| def run(self, args): | |||||
| if hasattr(args, 'run'): | |||||
| args.run(args) | |||||
| else: | |||||
| self.main(args) | |||||
| @@ -3,7 +3,74 @@ def init(args): | |||||
| print args.sitepath | print args.sitepath | ||||
| print args.force | print args.force | ||||
| print args.template | print args.template | ||||
| # Ensure sitepath is okay (refer to force parameter) | |||||
| # Find template by looking at the paths | |||||
| # 1. Environment Variable | |||||
| # 2. Hyde Data Directory | |||||
| # Throw exception on failure | |||||
| # Do not delete the site path, just overwrite existing files | |||||
| def gen(args): pass | def gen(args): pass | ||||
| def serve(args): pass | |||||
| def serve(args): pass | |||||
| from version import __version__ | |||||
| # """ | |||||
| # Implements the hyde entry point commands | |||||
| # """ | |||||
| # class Command(object): | |||||
| # """ | |||||
| # Base class for hyde commands | |||||
| # """ | |||||
| # def __init__(self, **kwargs): | |||||
| # super(Command, self).__init__(epilog='Use %(prog)s {command} -h to get help on individual commands', **kwargs) | |||||
| # self.subcommands = None | |||||
| # | |||||
| # def compose(self, commands, **kwargs): | |||||
| # self.subcommands = self.add_subparsers(**kwargs) | |||||
| # for command in commands: | |||||
| # self.subcommands.add_parser(command) | |||||
| # | |||||
| # def run(self, args=None): | |||||
| # """ | |||||
| # Executes the command | |||||
| # """ | |||||
| # options = {} | |||||
| # options.update(self.defaults) | |||||
| # if args: | |||||
| # options.update(args) | |||||
| # self.execute(options) | |||||
| # | |||||
| # def execute(self): | |||||
| # """ | |||||
| # Abstract method for the derived classes | |||||
| # """ | |||||
| # abstract | |||||
| # | |||||
| # class HydeCommand(Command): | |||||
| # """ | |||||
| # The parent command object. | |||||
| # """ | |||||
| # def __init__(self, **kwargs): | |||||
| # super(HydeCommand, self).__init__(**kwargs) | |||||
| # self.add_argument('--version', action='version', version='%(prog)s ' + __version__) | |||||
| # self.add_argument('-s', '--sitepath', action='store', default='.', help="Location of the hyde site") | |||||
| # | |||||
| # | |||||
| # class Initializer(Command): | |||||
| # """ | |||||
| # Represents the `hyde init` command | |||||
| # """ | |||||
| # def __init__(self, parent, **kwargs): | |||||
| # super(Initializer, self).__init__(**kwargs) | |||||
| # init_command.add_argument('-t', '--template', action='store', default='basic', dest='template', | |||||
| # help='Overwrite the current site if it exists') | |||||
| # init_command.add_argument('-f', '--force', action='store_true', default=False, dest='force', | |||||
| # help='Overwrite the current site if it exists') | |||||
| # | |||||
| # def run(self): | |||||
| # """ | |||||
| # | |||||
| # """ | |||||
| # pass | |||||
| @@ -1,19 +1,28 @@ | |||||
| """ | """ | ||||
| Hyde Template interface realization for Jinja2 | |||||
| Jinja template utilties | |||||
| """ | """ | ||||
| from hyde.template import Template | from hyde.template import Template | ||||
| from jinja2 import Environment, FileSystemLoader | from jinja2 import Environment, FileSystemLoader | ||||
| # pylint: disable-msg=W0104,E0602,W0613,R0201 | |||||
| class Jinja2Template(Template): | class Jinja2Template(Template): | ||||
| def configure(self, sitepath, config): | |||||
| """ | |||||
| The Jinja2 Template implementation | |||||
| """ | |||||
| def __init__(self, sitepath): | |||||
| super(Jinja2Template, self).__init__(sitepath) | |||||
| self.env = Environment(loader=FileSystemLoader(sitepath)) | |||||
| def configure(self, config): | |||||
| """ | """ | ||||
| Uses the config object to initialize the jinja environment. | Uses the config object to initialize the jinja environment. | ||||
| """ | """ | ||||
| self.env = Environment(loader=FileSystemLoader(sitepath)) | |||||
| pass | |||||
| def render(self, template_name, context): | def render(self, template_name, context): | ||||
| """ | """ | ||||
| Renders the given template using the context | Renders the given template using the context | ||||
| """ | """ | ||||
| t = self.env.get_template(template_name) | |||||
| return t.render(context) | |||||
| template = self.env.get_template(template_name) | |||||
| return template.render(context) | |||||
| @@ -1,9 +1,16 @@ | |||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
| # pylint: disable-msg=W0104,E0602,W0613,R0201 | |||||
| """ | """ | ||||
| Interface for hyde template engines. To use a different template engine, | |||||
| the following interface must be implemented. | |||||
| Abstract classes and utilities for template engines | |||||
| """ | """ | ||||
| class Template(object): | class Template(object): | ||||
| """ | |||||
| Interface for hyde template engines. To use a different template engine, | |||||
| the following interface must be implemented. | |||||
| """ | |||||
| def __init__(self, sitepath): | |||||
| self.sitepath = sitepath | |||||
| def configure(self, config): | def configure(self, config): | ||||
| """ | """ | ||||
| The config object is a simple YAML object with required settings. The template | The config object is a simple YAML object with required settings. The template | ||||
| @@ -12,7 +19,7 @@ class Template(object): | |||||
| """ | """ | ||||
| abstract | abstract | ||||
| def render(template_name, context): | |||||
| def render(self, template_name, context): | |||||
| """ | """ | ||||
| Given the name of a template (partial path usually), and the context, this function | Given the name of a template (partial path usually), and the context, this function | ||||
| must return the rendered string. | must return the rendered string. | ||||
| @@ -0,0 +1,36 @@ | |||||
| # -*- coding: utf-8 -*- | |||||
| """ | |||||
| Use nose | |||||
| `$ pip install nose` | |||||
| `$ nosetests` | |||||
| """ | |||||
| from hyde.command_line import Application, command, param | |||||
| from util import trap_exit | |||||
| from mock import Mock, patch | |||||
| @trap_exit | |||||
| def test_command_basic(): | |||||
| number_of_calls = 0 | |||||
| class TestCommandLine(Application): | |||||
| @command(description='test') | |||||
| @param('--force', action='store_true', dest='force1') | |||||
| @param('--force2', action='store', dest='force2') | |||||
| @param('--version', action='version', version='%(prog)s 1.0') | |||||
| def main(self, params): | |||||
| assert params.force1 == eval(params.force2) | |||||
| self._main() | |||||
| def _main(): pass | |||||
| with patch.object(TestCommandLine, '_main') as _main: | |||||
| c = TestCommandLine() | |||||
| args = c.parse(['--force', '--force2', 'True']) | |||||
| c.run(args) | |||||
| args = c.parse(['--force2', 'False']) | |||||
| c.run(args) | |||||
| assert _main.call_count == 2 | |||||
| @@ -7,7 +7,7 @@ Use nose | |||||
| Code borrowed from rwbench.py from the jinja2 examples | Code borrowed from rwbench.py from the jinja2 examples | ||||
| """ | """ | ||||
| from datetime import datetime | from datetime import datetime | ||||
| from hyde.ext.templates.jinja2Template import Jinja2Template | |||||
| from hyde.ext.templates.jinja import Jinja2Template | |||||
| from hyde.fs import File, Folder | from hyde.fs import File, Folder | ||||
| from jinja2.utils import generate_lorem_ipsum | from jinja2.utils import generate_lorem_ipsum | ||||
| from random import choice, randrange | from random import choice, randrange | ||||
| @@ -6,4 +6,15 @@ def assert_html_equals(expected, actual, sanitize=None): | |||||
| if sanitize: | if sanitize: | ||||
| expected = sanitize(expected) | expected = sanitize(expected) | ||||
| actual = sanitize(actual) | actual = sanitize(actual) | ||||
| assert expected == actual | |||||
| assert expected == actual | |||||
| def trap_exit(f): | |||||
| def test_wrapper(*args): | |||||
| try: | |||||
| f(*args) | |||||
| except SystemExit, e: | |||||
| print "Error running test [%s]" % f.__name__ | |||||
| print e.message | |||||
| raise e | |||||
| return test_wrapper | |||||
| @@ -1,267 +0,0 @@ | |||||
| [MASTER] | |||||
| # Profiled execution. | |||||
| profile=no | |||||
| # Add <file or directory> to the black list. It should be a base name, not a | |||||
| # path. You may set this option multiple times. | |||||
| #ignore=.svn | |||||
| # Pickle collected data for later comparisons. | |||||
| persistent=yes | |||||
| # Set the cache size for astng objects. | |||||
| cache-size=500 | |||||
| # List of plugins (as comma separated values of python modules names) to load, | |||||
| # usually to register additional checkers. | |||||
| load-plugins= | |||||
| [MESSAGES CONTROL] | |||||
| # Enable only checker(s) with the given id(s). This option conflicts with the | |||||
| # disable-checker option | |||||
| #enable-checker= | |||||
| # Enable all checker(s) except those with the given id(s). This option | |||||
| # conflicts with the enable-checker option | |||||
| #disable-checker=design | |||||
| # Enable all messages in the listed categories. | |||||
| #enable-msg-cat= | |||||
| # Disable all messages in the listed categories. | |||||
| #disable-msg-cat= | |||||
| # Enable the message(s) with the given id(s). | |||||
| #enable-msg= | |||||
| # Disable the message(s) with the given id(s). | |||||
| # List of all available ids: http://www.logilab.org/card/pylintfeatures | |||||
| # Disabled messages: | |||||
| # I0011: Locally disabling %s Used when an inline option disable a message or a messages category. | |||||
| disable-msg=I0011 | |||||
| [REPORTS] | |||||
| # set the output format. Available formats are text, parseable, colorized, msvs | |||||
| # (visual studio) and html | |||||
| output-format=text | |||||
| # Include message's id in output | |||||
| include-ids=yes | |||||
| # Put messages in a separate file for each module / package specified on the | |||||
| # command line instead of printing them on stdout. Reports (if any) will be | |||||
| # written in a file name "pylint_global.[txt|html]". | |||||
| files-output=no | |||||
| # Tells wether to display a full report or only the messages | |||||
| reports=yes | |||||
| # Python expression which should return a note less than 10 (10 is the highest | |||||
| # note).You have access to the variables errors warning, statement which | |||||
| # respectivly contain the number of errors / warnings messages and the total | |||||
| # number of statements analyzed. This is used by the global evaluation report | |||||
| # (R0004). | |||||
| evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) | |||||
| # Add a comment according to your evaluation note. This is used by the global | |||||
| # evaluation report (R0004). | |||||
| comment=no | |||||
| # Enable the report(s) with the given id(s). | |||||
| #enable-report= | |||||
| # Disable the report(s) with the given id(s). | |||||
| #disable-report= | |||||
| # checks for : | |||||
| # * doc strings | |||||
| # * modules / classes / functions / methods / arguments / variables name | |||||
| # * number of arguments, local variables, branchs, returns and statements in | |||||
| # functions, methods | |||||
| # * required module attributes | |||||
| # * dangerous default values as arguments | |||||
| # * redefinition of function / method / class | |||||
| # * uses of the global statement | |||||
| # | |||||
| [BASIC] | |||||
| # Required attributes for module, separated by a comma | |||||
| required-attributes= | |||||
| # Regular expression which should only match functions or classes name which do | |||||
| # not require a docstring | |||||
| no-docstring-rgx=__.*__ | |||||
| # Regular expression which should only match correct module names | |||||
| module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ | |||||
| # Regular expression which should only match correct module level names | |||||
| const-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__)|([a-z_][a-z0-9_]*))$ | |||||
| # Regular expression which should only match correct class names | |||||
| class-rgx=[_a-zA-Z0-9]+$ | |||||
| # Regular expression which should only match correct function names | |||||
| function-rgx=[a-z_][a-zA-Z0-9_]{2,40}$ | |||||
| # Regular expression which should only match correct method names | |||||
| method-rgx=[a-z_][a-zA-Z0-9_]{2,40}$ | |||||
| # Regular expression which should only match correct instance attribute names | |||||
| attr-rgx=[a-z_][a-z0-9_]{1,30}$ | |||||
| #alternative | |||||
| #attr-rgx=([a-z_][a-z0-9_]{2,30}|([a-z_][a-zA-Z0-9]{2,30}))$ | |||||
| # Regular expression which should only match correct argument names | |||||
| argument-rgx=[a-z_][a-z0-9_]{1,30}$ | |||||
| # Regular expression which should only match correct variable names | |||||
| variable-rgx=[a-z_][a-zA-Z0-9_]{1,30}$ | |||||
| # Regular expression which should only match correct list comprehension / | |||||
| # generator expression variable names | |||||
| inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ | |||||
| # Good variable names which should always be accepted, separated by a comma | |||||
| good-names=i,j,k,ex,Run,_ | |||||
| # Bad variable names which should always be refused, separated by a comma | |||||
| bad-names=foo,bar,baz,toto,tutu,tata | |||||
| # List of builtins function names that should not be used, separated by a comma | |||||
| bad-functions= | |||||
| # try to find bugs in the code using type inference | |||||
| # | |||||
| [TYPECHECK] | |||||
| # Tells wether missing members accessed in mixin class should be ignored. A | |||||
| # mixin class is detected if its name ends with "mixin" (case insensitive). | |||||
| ignore-mixin-members=yes | |||||
| # List of classes names for which member attributes should not be checked | |||||
| # (useful for classes with attributes dynamicaly set). | |||||
| ignored-classes=SQLObject | |||||
| # When zope mode is activated, consider the acquired-members option to ignore | |||||
| # access to some undefined attributes. | |||||
| zope=no | |||||
| # List of members which are usually get through zope's acquisition mecanism and | |||||
| # so shouldn't trigger E0201 when accessed (need zope=yes to be considered). | |||||
| acquired-members=REQUEST,acl_users,aq_parent | |||||
| # checks for | |||||
| # * unused variables / imports | |||||
| # * undefined variables | |||||
| # * redefinition of variable from builtins or from an outer scope | |||||
| # * use of variable before assigment | |||||
| # | |||||
| [VARIABLES] | |||||
| # Tells wether we should check for unused import in __init__ files. | |||||
| init-import=no | |||||
| # A regular expression matching names used for dummy variables (i.e. not used). | |||||
| dummy-variables-rgx=_|dummy | |||||
| # List of additional names supposed to be defined in builtins. Remember that | |||||
| # you should avoid to define new builtins when possible. | |||||
| additional-builtins= | |||||
| # checks for : | |||||
| # * methods without self as first argument | |||||
| # * overridden methods signature | |||||
| # * access only to existant members via self | |||||
| # * attributes not defined in the __init__ method | |||||
| # * supported interfaces implementation | |||||
| # * unreachable code | |||||
| # | |||||
| [CLASSES] | |||||
| # List of interface methods to ignore, separated by a comma. This is used for | |||||
| # instance to not check methods defines in Zope's Interface base class. | |||||
| ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by | |||||
| # List of method names used to declare (i.e. assign) instance attributes. | |||||
| defining-attr-methods=__init__,__new__,setUp | |||||
| # checks for | |||||
| # * external modules dependencies | |||||
| # * relative / wildcard imports | |||||
| # * cyclic imports | |||||
| # * uses of deprecated modules | |||||
| # | |||||
| [IMPORTS] | |||||
| # Deprecated modules which should not be used, separated by a comma | |||||
| deprecated-modules=regsub,string,TERMIOS,Bastion,rexec | |||||
| # Create a graph of every (i.e. internal and external) dependencies in the | |||||
| # given file (report R0402 must not be disabled) | |||||
| import-graph= | |||||
| # Create a graph of external dependencies in the given file (report R0402 must | |||||
| # not be disabled) | |||||
| ext-import-graph= | |||||
| # Create a graph of internal dependencies in the given file (report R0402 must | |||||
| # not be disabled) | |||||
| int-import-graph= | |||||
| # checks for : | |||||
| # * unauthorized constructions | |||||
| # * strict indentation | |||||
| # * line length | |||||
| # * use of <> instead of != | |||||
| # | |||||
| [FORMAT] | |||||
| # Maximum number of characters on a single line. | |||||
| max-line-length=120 | |||||
| # Maximum number of lines in a module | |||||
| max-module-lines=1000 | |||||
| # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 | |||||
| # tab). | |||||
| #indent-string=' ' | |||||
| # checks for: | |||||
| # * warning notes in the code like TODO | |||||
| # * PEP 263: source code with non ascii character but no encoding declaration | |||||
| # | |||||
| [MISCELLANEOUS] | |||||
| # List of note tags to take in consideration, separated by a comma. | |||||
| notes=TODO | |||||
| # checks for similarities and duplicated code. This computation may be | |||||
| # memory / CPU intensive, so you should disable it if you experiments some | |||||
| # problems. | |||||
| # | |||||
| [SIMILARITIES] | |||||
| # Minimum lines number of a similarity. | |||||
| min-similarity-lines=4 | |||||
| # Ignore comments when computing similarities. | |||||
| ignore-comments=yes | |||||
| # Ignore docstrings when computing similarities. | |||||
| ignore-docstrings=yes | |||||