@@ -0,0 +1,2413 @@
+%0Aimport os, sys%0A%0Aimport json%0Aimport yaml%0A%0Afrom log import logging%0ALOG = logging.getLogger(__name__)%0A%0A%0Aclass ConfigError(Exception):%0A    pass%0A%0A%0Aclass Config(object):%0A    scripts = %7B%7D%0A    job_templates = %7B%7D%0A    projects = %7B%7D%0A%0A    def load_scripts(self, scripts):%0A        for script in scripts:%0A            self._assert_new_item(%22script%22, script, self.scripts)%0A            self.scripts%5Bscript%5B%22name%22%5D%5D = script%0A%0A    def load_job_templates(self, job_templates):%0A        for jt in job_templates:%0A            self._assert_new_item(%22job-template%22, jt, self.job_templates)%0A            self.job_templates%5Bjt%5B%22name%22%5D%5D = jt%0A%0A    def load_projects(self, projects):%0A        for project in projects:%0A            self._assert_new_item(%22project%22, project, self.projects)%0A            self.projects%5Bproject%5B%22name%22%5D%5D = project%0A            common_attrs = project.get(%22job-common-attrs%22)%0A            if common_attrs:%0A                for job in project%5B%22jobs%22%5D:%0A                    job.update(common_attrs)%0A                    for jt in job.get(%22templates%22, %5B%5D):%0A                        jt = dict(self.job_templates%5Bjt%5D)%0A                        del(jt%5B%22name%22%5D)%0A                        job.update(jt)%0A%0A    def load_file(self, fname):%0A        data = yaml.safe_load(open(fname, %22rb%22))%0A        self.stream = data.get(%22stream%22, %7B%7D)%0A        self.logs = data.get(%22logs%22, %7B%7D)%0A        self.load_scripts(data.get(%22scripts%22, %5B%5D))%0A        self.load_job_templates(data.get(%22job-templates%22, %5B%5D))%0A        self.load_projects(data.get(%22projects%22, %5B%5D))%0A%0A    def _assert_new_item(self, item_name, item, items):%0A        if item%5B%22name%22%5D in items:%0A            msg = %22Duplicate %25s %25s%22 %25 item_name, item%5B%22name%22%5D%0A            LOG.error(msg)%0A            raise ConfigError(msg)%0A%0A    def load_dir(self, d):%0A        for dpath, dnames, fnames in os.walk(d):%0A            for fname in fnames:%0A                self.load_file(os.path.join(dpath, fname))%0A%0A    def load(self, dirs):%0A        for d in dirs:%0A            if d.startswith(%22~%22):%0A                d = os.path.expanduser(d)%0A            if os.path.isdir(d):%0A                self.load_dir(d)%0A            else:%0A                LOG.warning(%22Unable to load config from: %25s%22 %25 d)%0A%0A%0Aif __name__ == %22__main__%22:%0A    c = Config()%0A    c.load(%5B%22/etc/rallyci/%22, %22~/code/rally-ci/etc/rallyci%22%5D)%0A    print json.dumps(c.projects, indent=4)%0A    print json.dumps(c.job_templates, indent=4)%0A    print json.dumps(c.scripts, indent=4)%0A

Add config parser