123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import contextlib
- import os
- import yaml
- import sys
- from glob import glob
- @contextlib.contextmanager
- def pushd(newDir):
- previousDir = os.getcwd()
- os.chdir(newDir)
- try:
- yield
- finally:
- os.chdir(previousDir)
- class DependencyException(Exception):
- pass
- def deptree(sources, deps=None):
- if deps is None:
- deps = []
- deferred = []
- for name in sources.keys():
- source = sources[name]
- if "depends" not in source:
- deps.append(name)
- else:
- deferred.append(name)
- while deferred:
- name = deferred.pop()
- depends = sources[name]["depends"]
- # todo - detect dependency loop
- if name in depends:
- raise DependencyException('Source {} depends upon itself'.format(name))
- elif set(depends).issubset(set(deps)):
- deps.append(name)
- elif not set(depends).issubset(set(deps)):
- missing = ', '.join(set(depends).difference(set(deps)))
- raise DependencyException(
- 'Source {0} has missing dependencies: {1}'.format(name, missing))
- else:
- deferred.append(name)
- return deps
- def main(args):
- with pushd('etc/backup.d'):
- with open("backup.yml") as f:
- config = yaml.load(f)
- sources = {}
- for source in config['sources']:
- source = os.path.realpath(source)
- for path in glob('{}/*.yml'.format(source)):
- path = os.path.realpath(path)
- with pushd(os.path.dirname(path)), open(path) as f:
- data = yaml.load(f)
- if "depends" in data:
- for i in range(0, len(data["depends"])):
- data["depends"][i] = os.path.realpath(
- '{}.yml'.format(data["depends"][i]))
- sources[path] = data
- config['sources'] = sources
- import json
- for name in deptree(config["sources"]):
- source = config["sources"][name]
- print(json.dumps(source, indent=2))
- if __name__ == '__main__':
- try:
- main(sys.argv[1:])
- except DependencyException as ex:
- print(ex)
- sys.exit(1)
- except Exception:
- from traceback import format_exc
- msg = "Error encountered:\n" + format_exc().strip()
- print(msg)
- sys.exit(1)
|