# Path: pybombs/config_file.py
# class PBConfigFile(object):
#     """
#     Abstraction layer for our config and other files
#     """
#     def __init__(self, filename):
#         # Store normalized path, in case someone chdirs after calling the ctor
#         self._filename = os.path.abspath(os.path.expanduser(os.path.normpath(filename)))
#         self.data = None
#         self.yaml = AbstractYaml()
#         touch_file(filename)
#         with open(filename) as fn:
#             try:
#                 # TODO: Recursively turn this into an OrderedDict, not just at
#                 # top level. In a nested dict, some key elements will still be
#                 # ruamel.ordereddict.
#                 self.data = OrderedDict(self.yaml.load(fn.read()) or {})
#             except (IOError, OSError):
#                 self.data = OrderedDict()
#             except Exception as e:
#                 raise PBException("Error loading {0}: {1}".format(filename, str(e)))
#         assert isinstance(self.data, OrderedDict)
# 
#     def get(self, key=None, default=None):
#         " Return the data from the config file as a dict "
#         if key is None:
#             return self.data
#         if default is None:
#             default = OrderedDict()
#         # TODO Again, this is not recursive and sub-values may be non-vanilla
#         # ordered dicts
#         return OrderedDict(self.data.get(key, default))
# 
#     def save(self, newdata=None):
#         " Write the contents of the data cache to the file. "
#         if newdata is not None:
#             assert isinstance(newdata, dict)
#             self.data = newdata
#         fpath = os.path.split(self._filename)[0]
#         if len(fpath):
#             sysutils.mkdirp_writable(fpath)
#         with open(self._filename, 'w') as fn:
#             self.yaml.dump(self.data, fn)
# 
#     def update(self, newdata):
#         " Overwrite the data with newdata recursively. Updates the file. "
#         self.data = dict_merge(self.data, newdata)
#         self.save()
#         return self.data
# 
# Path: pybombs/recipe.py
# class PBPackageRequirement(object):
# class PBPackageRequirementPair(object):
# class PBPackageRequirementScanner(object):
# class Recipe(object):
#     def __init__(self, name):
#     def ev(self, func):
#     def __str__(self, lvl=0):
#     def __init__(self, pkg):
#     def ev(self, func):
#     def __str__(self, lvl=0):
#     def __init__(self, req_string):
#     def get_token_functor(self, token):
#     def pl_pkg(self, pkg_name):
#     def pl_lpar(self, par):
#     def pl_rpar(self, par):
#     def pl_cmp(self, cmpr):
#     def pl_ver(self, ver):
#     def pl_cmb(self, cmb):
#     def end_distro_pkg_expr(self):
#     def get_preq(self):
# def load_recipe_from_file(filename):
# def normalize_package_data(package_data_dict):
#     def __init__(self, filename):
#     def __str__(self):
#     def get_dict(self):
#     def get_package_reqs(self, pkg_type):
#     def set_static(self, static):
#     def get_command(self, cmd, static=None):
#     def var_replace_all(self, s):
#         def var_replace(mo, var_dict, cfg):
#     def get_local_package_data(self):
# def get_recipe(pkgname, target='package', fail_easy=False):
# RECIPE_CACHE = {}


import os
from six import iteritems
from pybombs.commands import CommandBase
from pybombs.config_file import PBConfigFile
from pybombs import recipe
from pybombs.pb_exception import PBException
        """
        self.cfg.load(prefix_dir)
        prefix = self.cfg.get_active_prefix()
        print("Linting prefix: `{0}'".format(prefix.prefix_dir))
        if prefix.src_dir is None or not os.path.isdir(prefix.src_dir):
            print("[HMM] - No source dir")
        if prefix.prefix_cfg_dir is None or not os.path.isdir(prefix.prefix_cfg_dir):
            print("[BAD] - No config dir")
        if prefix.inventory is None:
            print("[HMM] - No inventory")

    def _lint_recipe(self, recipe_file):
        """
        Check if recipe_file is a valid recipe
        """
        print("Linting recipe `{0}'".format(recipe_file))
        # Basic file checks
        try:
            recipe_dict = PBConfigFile(recipe_file).get()
        except IOError:
            self.log.error("Can't open `{0}'".format(recipe_file))
            return -1
        except AttributeError:
            self.log.error("Can't parse contents of file `{0}'".format(recipe_file))
            return -1
        if not isinstance(recipe_dict, dict):
            self.log.error("Invalid recipe file. Not a dict.")
            return -1
        # Try loading as recipe
        try:

# Path: pybombs/config_file.py
# class PBConfigFile(object):
#     """
#     Abstraction layer for our config and other files
#     """
#     def __init__(self, filename):
#         # Store normalized path, in case someone chdirs after calling the ctor
#         self._filename = os.path.abspath(os.path.expanduser(os.path.normpath(filename)))
#         self.data = None
#         self.yaml = AbstractYaml()
#         touch_file(filename)
#         with open(filename) as fn:
#             try:
#                 # TODO: Recursively turn this into an OrderedDict, not just at
#                 # top level. In a nested dict, some key elements will still be
#                 # ruamel.ordereddict.
#                 self.data = OrderedDict(self.yaml.load(fn.read()) or {})
#             except (IOError, OSError):
#                 self.data = OrderedDict()
#             except Exception as e:
#                 raise PBException("Error loading {0}: {1}".format(filename, str(e)))
#         assert isinstance(self.data, OrderedDict)
# 
#     def get(self, key=None, default=None):
#         " Return the data from the config file as a dict "
#         if key is None:
#             return self.data
#         if default is None:
#             default = OrderedDict()
#         # TODO Again, this is not recursive and sub-values may be non-vanilla
#         # ordered dicts
#         return OrderedDict(self.data.get(key, default))
# 
#     def save(self, newdata=None):
#         " Write the contents of the data cache to the file. "
#         if newdata is not None:
#             assert isinstance(newdata, dict)
#             self.data = newdata
#         fpath = os.path.split(self._filename)[0]
#         if len(fpath):
#             sysutils.mkdirp_writable(fpath)
#         with open(self._filename, 'w') as fn:
#             self.yaml.dump(self.data, fn)
# 
#     def update(self, newdata):
#         " Overwrite the data with newdata recursively. Updates the file. "
#         self.data = dict_merge(self.data, newdata)
#         self.save()
#         return self.data
# 
# Path: pybombs/recipe.py
# class PBPackageRequirement(object):
# class PBPackageRequirementPair(object):
# class PBPackageRequirementScanner(object):
# class Recipe(object):
#     def __init__(self, name):
#     def ev(self, func):
#     def __str__(self, lvl=0):
#     def __init__(self, pkg):
#     def ev(self, func):
#     def __str__(self, lvl=0):
#     def __init__(self, req_string):
#     def get_token_functor(self, token):
#     def pl_pkg(self, pkg_name):
#     def pl_lpar(self, par):
#     def pl_rpar(self, par):
#     def pl_cmp(self, cmpr):
#     def pl_ver(self, ver):
#     def pl_cmb(self, cmb):
#     def end_distro_pkg_expr(self):
#     def get_preq(self):
# def load_recipe_from_file(filename):
# def normalize_package_data(package_data_dict):
#     def __init__(self, filename):
#     def __str__(self):
#     def get_dict(self):
#     def get_package_reqs(self, pkg_type):
#     def set_static(self, static):
#     def get_command(self, cmd, static=None):
#     def var_replace_all(self, s):
#         def var_replace(mo, var_dict, cfg):
#     def get_local_package_data(self):
# def get_recipe(pkgname, target='package', fail_easy=False):
# RECIPE_CACHE = {}


# Path: pybombs/commands/lint.py
import os
from six import iteritems
from pybombs.commands import CommandBase
from pybombs.config_file import PBConfigFile
from pybombs import recipe
from pybombs.pb_exception import PBException

        """
        self.cfg.load(prefix_dir)
        prefix = self.cfg.get_active_prefix()
        print("Linting prefix: `{0}'".format(prefix.prefix_dir))
        if prefix.src_dir is None or not os.path.isdir(prefix.src_dir):
            print("[HMM] - No source dir")
        if prefix.prefix_cfg_dir is None or not os.path.isdir(prefix.prefix_cfg_dir):
            print("[BAD] - No config dir")
        if prefix.inventory is None:
            print("[HMM] - No inventory")

    def _lint_recipe(self, recipe_file):
        """
        Check if recipe_file is a valid recipe
        """
        print("Linting recipe `{0}'".format(recipe_file))
        # Basic file checks
        try:
            recipe_dict = PBConfigFile(recipe_file).get()
        except IOError:
            self.log.error("Can't open `{0}'".format(recipe_file))
            return -1
        except AttributeError:
            self.log.error("Can't parse contents of file `{0}'".format(recipe_file))
            return -1
        if not isinstance(recipe_dict, dict):
            self.log.error("Invalid recipe file. Not a dict.")
            return -1
        # Try loading as recipe
        try:

            rec = recipe.Recipe(recipe_file)