From 12dc0d2bddcbb55c98727126f2fd0747edd87060 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 6 Oct 2011 17:15:45 +0200 Subject: [PATCH 1/2] cleanup and file system backed properties Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 58 ++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index 80c2c351..127bf038 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -20,9 +20,13 @@ # import os +import collections import cdist -import cdist.path +import cdist.core.property + + +DOT_CDIST = '.cdist' class Object(object): @@ -73,27 +77,64 @@ class Object(object): """Return a list of object names""" for path, dirs, files in os.walk(cls.base_dir()): # FIXME: use constant instead of string - if cdist.path.DOT_CDIST in dirs: + if DOT_CDIST in dirs: yield os.path.relpath(path, cls.base_dir()) - def __init__(self, type, object_id=None, parameter=None, requirements=None): + def __init__(self, type, object_id=None, parameters=None, requirements=None): self.type = type # instance of Type self.object_id = object_id - self.qualified_name = os.path.join(self.type.name, self.object_id) - self.parameter = parameter or {} + self.name = os.path.join(self.type.name, self.object_id) + self.parameters = parameters or {} self.requirements = requirements or [] + + self.__parameters = None + self.__requirements = None def __repr__(self): - return '' % self.qualified_name + return '' % self.name @property def path(self): return os.path.join( self.base_dir(), - self.qualified_name, - cdist.path.DOT_CDIST + self.name, + DOT_CDIST ) + + ### requirements + @property + def requirements(self): + if not self.__requirements: + self.__requirements = cdist.core.property.FileList(os.path.join(self.path, "require")) + return self.__requirements + + @requirements.setter + def requirements(self, value): + if isinstance(value, cdist.core.property.FileList): + self.__requirements = value + else: + self.__requirements = cdist.core.property.FileList(os.path.join(self.path, "require"), value) + ### /requirements + + + ### parameters + @property + def parameters(self): + if not self.__parameters: + self.__parameters = cdist.core.property.DirectoryDict(os.path.join(self.path, "parameter")) + return self.__parameters + + @parameters.setter + def parameters(self, value): + if isinstance(value, cdist.core.property.DirectoryDict): + self.__parameters = value + else: + self.__parameters = cdist.core.property.DirectoryDict(os.path.join(self.path, "parameter"), value) + ### /parameters + + + ### changed @property def changed(self): """Check whether the object has been changed.""" @@ -111,5 +152,6 @@ class Object(object): except EnvironmentError: # ignore pass + ### /changed # FIXME: implement other properties/methods From 3a1cea68873f585529dcfab5b0d7dc3a7df58942 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 6 Oct 2011 17:16:12 +0200 Subject: [PATCH 2/2] file system backed properties Signed-off-by: Steven Armstrong --- lib/cdist/core/property.py | 119 +++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 lib/cdist/core/property.py diff --git a/lib/cdist/core/property.py b/lib/cdist/core/property.py new file mode 100644 index 00000000..e22e33cd --- /dev/null +++ b/lib/cdist/core/property.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +# +# 2010-2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# + +import os +import collections + +import cdist + + +DOT_CDIST = '.cdist' + + +class FileList(collections.MutableSequence): + """A list that stores it's state in a file. + + """ + def __init__(self, path, initial=None): + self._path = path + if initial: + for i in initial: + self.append(i) + + def __read(self): + lines = [] + try: + with open(self._path) as fd: + for line in fd: + lines.append(line.strip()) + except EnvironmentError as e: + # error ignored + pass + return lines + + def __write(self, lines): + try: + with open(self._path, 'w') as fd: + for line in lines: + fd.write(line + '\n') + except EnvironmentError as e: + # error ignored + raise + + def __repr__(self): + return repr(list(self)) + + def __getitem__(self, index): + return self.__read()[index] + + def __setitem__(self, index, value): + lines = self.__read() + lines[index] = value + self.__write(lines) + + def __delitem__(self, index): + lines = self.__read() + del lines[index] + self.__write(lines) + + def __len__(self): + lines = self.__read() + return len(lines) + + def insert(self, index, value): + lines = self.__read() + lines.insert(index, value) + self.__write(lines) + + +class DirectoryDict(collections.MutableMapping): + """A dict that stores it's state in a directory. + + """ + def __init__(self, path, dict=None, **kwargs): + self._path = path + if dict is not None: + self.update(dict) + if len(kwargs): + self.update(kwargs) + + def __repr__(self): + return repr(dict(self)) + + def __getitem__(self, key): + try: + with open(os.path.join(self._path, key), "r") as fd: + return fd.read() + except EnvironmentError: + raise KeyError(key) + + def __setitem__(self, key, value): + with open(os.path.join(self._path, key), "w") as fd: + fd.write(value) + + def __delitem__(self, key): + os.remove(os.path.join(self._path, key)) + + def __iter__(self): + return iter(os.listdir(self._path)) + + def __len__(self): + return len(os.listdir(self._path))