diff options
Diffstat (limited to 'morphlib/definitions.py')
-rw-r--r-- | morphlib/definitions.py | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/morphlib/definitions.py b/morphlib/definitions.py new file mode 100644 index 00000000..09838236 --- /dev/null +++ b/morphlib/definitions.py @@ -0,0 +1,133 @@ +# Copyright (C) 2014 Codethink Limited +# +# This program 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; version 2 of the License. +# +# This program 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 this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# =*= License: GPL-2 =*= + +import yaml +import os +import yapp +import cache +from subprocess import check_output + + +class Definitions(): + __definitions = [] + __trees = {} + + def __init__(self): + ''' Load all definitions from `cwd` tree. ''' + if self.__definitions != []: + return + + for dirname, dirnames, filenames in os.walk(os.getcwd()): + for filename in filenames: + if not (filename.endswith('.def') or + filename.endswith('.morph')): + continue + + this = self._load(dirname, filename) + name = self.lookup(this, 'name') + if this.get('name'): + self._insert(this) + + for dependency in self.lookup(this, 'build-depends'): + if self.lookup(dependency, 'repo') != []: + self._insert(dependency) + + for component in (self.lookup(this, 'contents') + + self.lookup(this, 'chunks') + + self.lookup(this, 'strata')): + component['build-depends'] = ( + self.lookup(component, 'build-depends')) + for dependency in self.lookup(this, 'build-depends'): + component['build-depends'].extend( + [self.lookup(dependency, 'name')]) + self._insert(component) + + if '.git' in dirnames: + dirnames.remove('.git') + + try: + self.__trees = self._load(os.getcwd(), ".trees") + for definition in self.__definitions: + definition['tree'] = self.__trees.get(definition['name']) + + except Exception, e: + return + + def _load(self, path, name): + ''' Load a single definition file, and create a hash for it. ''' + try: + filename = os.path.join(path, name) + with open(filename) as f: + text = f.read() + + definition = yaml.safe_load(text) + except ValueError: + flog(this, 'ERROR: problem loading', filename) + + return definition + + def _insert(self, this): + for i, definition in enumerate(self.__definitions): + if definition['name'] == this['name']: + if (self.lookup(definition, 'ref') == [] + or self.lookup(this, 'ref') == []): + for key in this: + definition[key] = this[key] + + return + + for key in this: + if key == 'build-depends' or key == 'morph': + continue + if definition.get(key) != this[key]: + yapp.log(this, 'WARNING: multiple definitions of', key) + yapp.log(this, '%s | %s' % (definition.get(key), + this[key])) + + self.__definitions.append(this) + + def get(self, this): + for definition in self.__definitions: + if (definition['name'] == this or + definition['name'] == self.lookup(this, 'name')): + return definition + + yapp.log(this, 'ERROR: no definition found for', this) + raise SystemExit + + def lookup(self, thing, value): + ''' Look up value from thing, return [] if none. ''' + val = [] + try: + val = thing[value] + except Exception, e: + pass + return val + + def version(self, this): + try: + return this['name'].split('@')[1] + except Exception, e: + return False + + def save_trees(self): + self.__trees = {} + for definition in self.__definitions: + if definition.get('tree') is not None: + self.__trees[definition['name']] = definition.get('tree') + with open(os.path.join(os.getcwd(), '.trees'), 'w') as f: + f.write(yaml.dump(self.__trees, default_flow_style=False)) |