Browse Source

`hyde serve` now picks up changes in config data automatically. (Issue #24)

main
Lakshmi Vyasarajan 13 years ago
parent
commit
65828484a4
7 changed files with 74 additions and 22 deletions
  1. +7
    -0
      CHANGELOG.rst
  2. +23
    -11
      hyde/generator.py
  3. +19
    -2
      hyde/model.py
  4. +1
    -2
      hyde/server.py
  5. +22
    -4
      hyde/site.py
  6. +0
    -1
      hyde/tests/ext/test_sorter.py
  7. +2
    -2
      hyde/tests/test_generate.py

+ 7
- 0
CHANGELOG.rst View File

@@ -1,3 +1,10 @@
Version 0.8.3c11
=================

* `hyde serve` now picks up changes in config data automatically.
(Issue #24)


Version 0.8.3c10 Version 0.8.3c10
=============== ===============




+ 23
- 11
hyde/generator.py View File

@@ -27,15 +27,19 @@ class Generator(object):
self.site = site self.site = site
self.generated_once = False self.generated_once = False
self.deps = Dependents(site.sitepath) self.deps = Dependents(site.sitepath)
self.create_context()
self.template = None
Plugin.load_all(site)

self.events = Plugin.get_proxy(self.site)

def create_context(self):
site = self.site
self.__context__ = dict(site=site) self.__context__ = dict(site=site)
if hasattr(site.config, 'context'): if hasattr(site.config, 'context'):
site.context = Context.load(site.sitepath, site.config.context) site.context = Context.load(site.sitepath, site.config.context)
self.__context__.update(site.context) self.__context__.update(site.context)


self.template = None
Plugin.load_all(site)

self.events = Plugin.get_proxy(self.site)


@contextmanager @contextmanager
def context_for_resource(self, resource): def context_for_resource(self, resource):
@@ -43,8 +47,6 @@ class Generator(object):
Context manager that intializes the context for a given Context manager that intializes the context for a given
resource and rolls it back after the resource is processed. resource and rolls it back after the resource is processed.
""" """
# TODO: update metadata and other resource
# specific properties here.
self.__context__.update( self.__context__.update(
resource=resource, resource=resource,
node=resource.node, node=resource.node,
@@ -103,10 +105,7 @@ class Generator(object):
Checks if the site requries a reload and loads if Checks if the site requries a reload and loads if
necessary. necessary.
""" """
#TODO: Perhaps this is better suited in Site
if not len(self.site.content.child_nodes):
logger.info("Reading site contents")
self.site.load()
self.site.reload_if_needed()


def finalize(self): def finalize(self):
""" """
@@ -154,8 +153,9 @@ class Generator(object):
last generation. last generation.
""" """
logger.debug("Checking for changes in %s" % resource) logger.debug("Checking for changes in %s" % resource)
self.load_site_if_needed()
self.load_template_if_needed() self.load_template_if_needed()
self.load_site_if_needed()

target = File(self.site.config.deploy_root_path.child( target = File(self.site.config.deploy_root_path.child(
resource.relative_deploy_path)) resource.relative_deploy_path))
if not target.exists or target.older_than(resource.source_file): if not target.exists or target.older_than(resource.source_file):
@@ -164,6 +164,11 @@ class Generator(object):
if resource.source_file.is_binary: if resource.source_file.is_binary:
logger.debug("No Changes found in %s" % resource) logger.debug("No Changes found in %s" % resource)
return False return False
if self.site.config.needs_refresh() or \
not target.has_changed_since(self.site.config.last_modified):
logger.debug("Site configuration changed")
return True

deps = self.get_dependencies(resource) deps = self.get_dependencies(resource)
if not deps or None in deps: if not deps or None in deps:
logger.debug("No changes found in %s" % resource) logger.debug("No changes found in %s" % resource)
@@ -282,8 +287,14 @@ class Generator(object):
except HydeException: except HydeException:
self.generate_all() self.generate_all()


def refresh_config(self):
if self.site.config.needs_refresh():
logger.debug("Refreshing configuration and context")
self.site.refresh_config()
self.create_context()


def __generate_node__(self, node, incremental=False): def __generate_node__(self, node, incremental=False):
self.refresh_config()
for node in node.walk(): for node in node.walk():
logger.debug("Generating Node [%s]", node) logger.debug("Generating Node [%s]", node)
self.events.begin_node(node) self.events.begin_node(node)
@@ -293,6 +304,7 @@ class Generator(object):




def __generate_resource__(self, resource, incremental=False): def __generate_resource__(self, resource, incremental=False):
self.refresh_config()
if not resource.is_processable: if not resource.is_processable:
logger.debug("Skipping [%s]", resource) logger.debug("Skipping [%s]", resource)
return return


+ 19
- 2
hyde/model.py View File

@@ -6,8 +6,9 @@ from hyde.fs import File, Folder


import codecs import codecs
import yaml import yaml
from datetime import datetime
from UserDict import IterableUserDict from UserDict import IterableUserDict

from hyde.util import getLoggerWithNullHandler from hyde.util import getLoggerWithNullHandler
logger = getLoggerWithNullHandler('hyde.engine') logger = getLoggerWithNullHandler('hyde.engine')


@@ -135,13 +136,27 @@ class Config(Expando):
plugins = [], plugins = [],
ignore = [ "*~", "*.bak" ] ignore = [ "*~", "*.bak" ]
) )
conf = dict(**default_config)
self.config_file = config_file
self.config_dict = config_dict
self.load_time = datetime.min
self.config_files = []
self.sitepath = Folder(sitepath) self.sitepath = Folder(sitepath)
conf = dict(**default_config)
conf.update(self.read_config(config_file)) conf.update(self.read_config(config_file))
if config_dict: if config_dict:
conf.update(config_dict) conf.update(config_dict)
super(Config, self).__init__(conf) super(Config, self).__init__(conf)


@property
def last_modified(self):
return max((conf.last_modified for conf in self.config_files))

def needs_refresh(self):
if not self.config_files:
return True
return any((conf.has_changed_since(self.load_time)
for conf in self.config_files))

def read_config(self, config_file): def read_config(self, config_file):
""" """
Reads the configuration file and updates this Reads the configuration file and updates this
@@ -152,6 +167,7 @@ class Config(Expando):
config_file else 'site.yaml') config_file else 'site.yaml')
conf = {} conf = {}
if File(conf_file).exists: if File(conf_file).exists:
self.config_files.append(File(conf_file))
logger.info("Reading site configuration from [%s]", conf_file) logger.info("Reading site configuration from [%s]", conf_file)
with codecs.open(conf_file, 'r', 'utf-8') as stream: with codecs.open(conf_file, 'r', 'utf-8') as stream:
conf = yaml.load(stream) conf = yaml.load(stream)
@@ -159,6 +175,7 @@ class Config(Expando):
parent = self.read_config(conf['extends']) parent = self.read_config(conf['extends'])
parent.update(conf) parent.update(conf)
conf = parent conf = parent
self.load_time = datetime.now()
return conf return conf






+ 1
- 2
hyde/server.py View File

@@ -8,6 +8,7 @@ import select
import threading import threading
import urlparse import urlparse
import urllib import urllib
from datetime import datetime
from SimpleHTTPServer import SimpleHTTPRequestHandler from SimpleHTTPServer import SimpleHTTPRequestHandler
from BaseHTTPServer import HTTPServer from BaseHTTPServer import HTTPServer
from hyde.fs import File, Folder from hyde.fs import File, Folder
@@ -18,8 +19,6 @@ from hyde.exceptions import HydeException
from hyde.util import getLoggerWithNullHandler from hyde.util import getLoggerWithNullHandler
logger = getLoggerWithNullHandler('hyde.server') logger = getLoggerWithNullHandler('hyde.server')


from datetime import datetime

class HydeRequestHandler(SimpleHTTPRequestHandler): class HydeRequestHandler(SimpleHTTPRequestHandler):
""" """
Serves files by regenerating the resource (or) Serves files by regenerating the resource (or)


+ 22
- 4
hyde/site.py View File

@@ -5,12 +5,13 @@ Parses & holds information about the site to be generated.
import os import os
import fnmatch import fnmatch
import urlparse import urlparse
from functools import wraps

from hyde.exceptions import HydeException from hyde.exceptions import HydeException
from hyde.fs import FS, File, Folder from hyde.fs import FS, File, Folder
from hyde.model import Config from hyde.model import Config

from hyde.util import getLoggerWithNullHandler from hyde.util import getLoggerWithNullHandler
from functools import wraps


def path_normalized(f): def path_normalized(f):
@wraps(f) @wraps(f)
@@ -359,7 +360,6 @@ class RootNode(Node):
return return
self.add_resource(afile) self.add_resource(afile)



class Site(object): class Site(object):
""" """
Represents the site to be generated. Represents the site to be generated.
@@ -373,11 +373,29 @@ class Site(object):
self.plugins = [] self.plugins = []
self.context = {} self.context = {}


def refresh_config(self):
"""
Refreshes config data if one or more config files have
changed. Note that this does not refresh the meta data.
"""
if self.config.needs_refresh():
logger.debug("Refreshing config data")
self.config = Config(self.sitepath,
self.config.config_file,
self.config.config_dict)

def reload_if_needed(self):
"""
Reloads if the site has not been loaded before or if the
configuration has changed since the last load.
"""
if not len(self.content.child_nodes):
self.load()

def load(self): def load(self):
""" """
Walks the content and media folders to load up the sitemap. Walks the content and media folders to load up the sitemap.
""" """

self.content.load() self.content.load()


def content_url(self, path): def content_url(self, path):


+ 0
- 1
hyde/tests/ext/test_sorter.py View File

@@ -303,7 +303,6 @@ class TestSorterMeta(object):
"another-sad-post.html", "another-sad-post.html",
"happy-post.html"] "happy-post.html"]
for r in s.content.walk_resources(): for r in s.content.walk_resources():
print r.meta.to_dict()
expected = r.name in have_index expected = r.name in have_index
assert attributes_checker(r, ['meta.index']) == expected assert attributes_checker(r, ['meta.index']) == expected




+ 2
- 2
hyde/tests/test_generate.py View File

@@ -77,9 +77,9 @@ class TestGenerator(object):
resource = site.content.resource_from_path(TEST_SITE.child('content/about.html')) resource = site.content.resource_from_path(TEST_SITE.child('content/about.html'))
gen = Generator(site) gen = Generator(site)
gen.generate_all() gen.generate_all()
assert not gen.has_resource_changed(resource)
import time import time
time.sleep(1) time.sleep(1)
assert not gen.has_resource_changed(resource)
text = resource.source_file.read_all() text = resource.source_file.read_all()
resource.source_file.write(text) resource.source_file.write(text)
assert gen.has_resource_changed(resource) assert gen.has_resource_changed(resource)
@@ -160,4 +160,4 @@ main:
assert "abc = def" in out assert "abc = def" in out
assert "home" in out assert "home" in out
assert "articles" in out assert "articles" in out
assert "projects" in out
assert "projects" in out

Loading…
Cancel
Save