aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bachelier <laurent@bachelier.name>2010-01-05 01:21:14 +0100
committerLaurent Bachelier <laurent@bachelier.name>2010-01-05 01:21:14 +0100
commita65fc04bf7a025e36c64188d142b847154ddf47b (patch)
treebc3b75af9fca0bc2a056f8d6fae853cf5f2d24ee
parentFirst import (diff)
downloadconfman-a65fc04bf7a025e36c64188d142b847154ddf47b.tar.xz
Support for conditional dotfiles
It executes python code under a limited environment (it is not designed to be secure, it is thought for laziness). Also uses a new "options" attribute.
-rw-r--r--confman.py56
-rwxr-xr-xexample.py9
2 files changed, 63 insertions, 2 deletions
diff --git a/confman.py b/confman.py
index 41125fd..98f0552 100644
--- a/confman.py
+++ b/confman.py
@@ -41,6 +41,10 @@ class SymlinkConfigAction(ConfigAction):
return filename
def check(self):
+ source = self.source_path()
+ if not os.path.exists(source):
+ raise Exception("Source does not exists")
+
dest = self.dest_path()
if os.path.lexists(dest):
if not os.path.islink(dest):
@@ -62,10 +66,54 @@ class SymlinkConfigAction(ConfigAction):
print "Created new link: "+dest+" => "+source
os.symlink(source, dest)
+
class CopyConfigAction(ConfigAction):
pass #TODO
+class ProgrammableConfigAction(ConfigAction):
+ matched = re.compile("\.p\.py$")
+
+ @classmethod
+ def matches(cls, filename):
+ if cls.matched.search(filename):
+ return cls.matched.sub("", filename)
+ return False
+
+ def check(self):
+ #TODO ignore()
+ class SymlinkForwarder(Exception):
+ def __init__(self, filename):
+ self.filename = filename
+
+ def redirect(filename):
+ raise SymlinkForwarder("_"+filename)
+
+ exec_env = \
+ {
+ "options": self.config.options,
+ "redirect": redirect
+ }
+
+ source = self.source_path()
+ try:
+ exec compile(open(source).read(), source, 'exec') \
+ in exec_env
+ except SymlinkForwarder as e:
+ self.proxy = SymlinkConfigAction(self.config, self.relpath, e.filename, self.dest)
+ else:
+ raise Exception("Unknown result")
+
+ return self.proxy.check()
+
+ def sync(self):
+ return self.proxy.sync()
+
+ def __repr__(self):
+ return self.__class__.__name__+': '+self.source+' => PROXY '+repr(self.proxy)
+
+
+
class IgnoreConfigAction(ConfigAction):
ignored = re.compile("_|\.git$|\.gitignore$")
@@ -80,7 +128,7 @@ class IgnoreConfigAction(ConfigAction):
class ConfigSource(object):
- def __init__(self, source, dest, classes = None):
+ def __init__(self, source, dest, classes = None, options = None):
# handle '~'
self.source = os.path.expanduser(source)
self.dest = os.path.expanduser(dest)
@@ -89,10 +137,16 @@ class ConfigSource(object):
self.classes = classes
else:
self.classes = [
+ ProgrammableConfigAction,
IgnoreConfigAction,
SymlinkConfigAction,
]
+ if options:
+ self.options = options
+ else:
+ self.options = []
+
def analyze(self):
def walker(_, path, files):
relpath = os.path.relpath(path, self.source)
diff --git a/example.py b/example.py
index ade298e..913c5ec 100755
--- a/example.py
+++ b/example.py
@@ -2,10 +2,17 @@
from confman import ConfigSource
-c = ConfigSource("~/dotfiles", "/tmp/dotfiles-test")
+options = \
+{
+ 'tags': ['desktop'],
+ 'hostname': 'test',
+}
+
+c = ConfigSource("~/dotfiles", "/tmp/dotfiles-test", None, options)
c.analyze()
c.check()
c.sync()
+print
from pprint import pprint
pprint(c)