# Path: servi/manifest.py
# class Manifest(object):
#     def __init__(self, source, load=False):
#         assert source in [c.TEMPLATE, c.MASTER]
#         self.source = source
#         self.fname = pathfor(c.MANIFEST_FILE, source)
#         self.manifest = None
#         self.template_version = None
#         if load:
#             self._load()
#         else:
#             self._create()
# 
#     def _create(self):
#         # create a new manifest
#         # use the files in TMPL_DIR_SITE as the source list
#         self.template_version = SemanticVersion(get_template_version())
# 
#         self.manifest = {
#             "files": {},
#             "template_version": str(self.template_version),
#         }
# 
#         for (dirpath, dirnames, filenames) in os.walk(c.TMPL_DIR_SITE):
#             for file in filenames:
#                 # Keep the version file and manifest files out of the manifest
#                 if file == c.VERSION_FILE or file == c.MANIFEST_FILE:
#                     continue
# 
#                 if file == c.SERVIFILE_GLOBAL and self.source is c.MASTER:
#                     self.manifest["files"][file] = \
#                         hash_of_file(c.SERVIFILE_GLOBAL_FULL)
#                 else:
#                     template_file = os.path.join(dirpath, file)
#                     if self.source is c.MASTER:
#                         hashv = hash_of_file(
#                             templatepath_to_destpath(template_file))
#                     else:
#                         hashv = hash_of_file(template_file)
# 
#                     fname = normalize_path(template_file, c.TEMPLATE)
#                     self.manifest["files"][fname] = hashv
# 
#     def _load(self):
#         with open(self.fname, 'r') as fp:
#             self.manifest = json.load(fp)
#         self.template_version = SemanticVersion(
#             self.manifest["template_version"])
# 
#     def save(self):
#         assert c.MANIFEST_FILE not in self.manifest["files"]
# 
#         with open(self.fname, 'w') as fp:
#             json.dump(self.manifest, fp, indent=4, sort_keys=True)
# 
#     @staticmethod
#     def equal_versions(m1, m2):
#         return (SemanticVersion(m1.manifest["template_version"]) ==
#                 SemanticVersion(m2.manifest["template_version"]))
# 
#     @staticmethod
#     def equal_files(m1, m2):
#         if not m1 or not m2:
#             return False
# 
#         diff = DictDiffer(m1.manifest["files"], m2.manifest["files"])
#         return set() == diff.added() | diff.changed() | diff.removed()
# 
#     def __eq__(self, other):
#         return (Manifest.equal_versions(self, other) and
#                 Manifest.equal_files(self, other))
# 
#     @staticmethod
#     def diff_files(m1, m0):
#         mod_m0 = {k: v for k, v in m0.manifest["files"].items()
#                   if v != c.MISSING_HASH}
# 
#         mod_m1 = {k: v for k, v in m1.manifest["files"].items()
#                   if v != c.MISSING_HASH}
# 
#         diff = DictDiffer(mod_m1, mod_m0)
#         return diff.added(), diff.changed(), diff.removed()
# 
# Path: servi/exceptions.py
# class ServiError(Exception):
#     # Expected errrors. Handle gracefully (ie: no stack dump)
#     def __init__(self, msg=None):
#         self.msg = msg
# 
#     def __str__(self):
#         return (
#             '\n***** ERROR *****\n'
#             '{0}\n'
#             '\n**Servi Aborting**'.format(self.msg))
# 
# class ForceError(Exception):
#     def __init__(self, msg=None):
#         self.msg = msg
# 
#     def __str__(self):
#         return (
#             '\n***** ERROR *****\n'
#             '{0}\n'
#             'Use -f / --force to override.\n'
#             '\n**Servi Aborting**'.format(self.msg))
# 
# Path: servi/utils.py
# def file_exists(path):
#     return os.path.isfile(path) and os.access(path, os.R_OK)
# 
# def pathfor(fname, source):
#     if source is c.MASTER and fname == c.SERVIFILE_GLOBAL:
#         return c.SERVIFILE_GLOBAL_FULL
#     else:
#         return c.pathfor(fname, source, c.TEMPLATE, c.MASTER, c.TMPL_DIR_SITE,
#                          c.MASTER_DIR)


from datetime import datetime
from logging import debug
from servi.manifest import Manifest
from servi.exceptions import ServiError, ForceError
from servi.utils import file_exists, pathfor
import re
import shutil
import os
import yaml
import servi.config as c
            if fname == c.SERVIFILE_GLOBAL:
                master_fname = c.SERVIFILE_GLOBAL_FULL

            # Deal with .git files - used by included submodules - ignore
            # (template files are just files - too confusing to leave as
            #  submodules!)
            if (os.path.split(fname)[1] == '.git'
                    and os.path.isfile(template_fname)):
                debug('Skipping .git file (submodule marker): {0}'
                      .format(fname))
                continue

            # Always backup (never overwrite) master
            if file_exists(master_fname):
                self.rename_master_file(fname, self.timestamp)
                existing = True
            else:
                existing = False

            # Copy template to master
            destdir = os.path.dirname(master_fname)
            if destdir and not os.path.exists(destdir):
                os.makedirs(destdir)
            shutil.copy2(template_fname, master_fname)
            if existing:
                debug('Updated: {0}'.format(master_fname))
            else:
                debug('Created: {0}'.format(master_fname))

        # Recreate the master manifest

# Path: servi/manifest.py
# class Manifest(object):
#     def __init__(self, source, load=False):
#         assert source in [c.TEMPLATE, c.MASTER]
#         self.source = source
#         self.fname = pathfor(c.MANIFEST_FILE, source)
#         self.manifest = None
#         self.template_version = None
#         if load:
#             self._load()
#         else:
#             self._create()
# 
#     def _create(self):
#         # create a new manifest
#         # use the files in TMPL_DIR_SITE as the source list
#         self.template_version = SemanticVersion(get_template_version())
# 
#         self.manifest = {
#             "files": {},
#             "template_version": str(self.template_version),
#         }
# 
#         for (dirpath, dirnames, filenames) in os.walk(c.TMPL_DIR_SITE):
#             for file in filenames:
#                 # Keep the version file and manifest files out of the manifest
#                 if file == c.VERSION_FILE or file == c.MANIFEST_FILE:
#                     continue
# 
#                 if file == c.SERVIFILE_GLOBAL and self.source is c.MASTER:
#                     self.manifest["files"][file] = \
#                         hash_of_file(c.SERVIFILE_GLOBAL_FULL)
#                 else:
#                     template_file = os.path.join(dirpath, file)
#                     if self.source is c.MASTER:
#                         hashv = hash_of_file(
#                             templatepath_to_destpath(template_file))
#                     else:
#                         hashv = hash_of_file(template_file)
# 
#                     fname = normalize_path(template_file, c.TEMPLATE)
#                     self.manifest["files"][fname] = hashv
# 
#     def _load(self):
#         with open(self.fname, 'r') as fp:
#             self.manifest = json.load(fp)
#         self.template_version = SemanticVersion(
#             self.manifest["template_version"])
# 
#     def save(self):
#         assert c.MANIFEST_FILE not in self.manifest["files"]
# 
#         with open(self.fname, 'w') as fp:
#             json.dump(self.manifest, fp, indent=4, sort_keys=True)
# 
#     @staticmethod
#     def equal_versions(m1, m2):
#         return (SemanticVersion(m1.manifest["template_version"]) ==
#                 SemanticVersion(m2.manifest["template_version"]))
# 
#     @staticmethod
#     def equal_files(m1, m2):
#         if not m1 or not m2:
#             return False
# 
#         diff = DictDiffer(m1.manifest["files"], m2.manifest["files"])
#         return set() == diff.added() | diff.changed() | diff.removed()
# 
#     def __eq__(self, other):
#         return (Manifest.equal_versions(self, other) and
#                 Manifest.equal_files(self, other))
# 
#     @staticmethod
#     def diff_files(m1, m0):
#         mod_m0 = {k: v for k, v in m0.manifest["files"].items()
#                   if v != c.MISSING_HASH}
# 
#         mod_m1 = {k: v for k, v in m1.manifest["files"].items()
#                   if v != c.MISSING_HASH}
# 
#         diff = DictDiffer(mod_m1, mod_m0)
#         return diff.added(), diff.changed(), diff.removed()
# 
# Path: servi/exceptions.py
# class ServiError(Exception):
#     # Expected errrors. Handle gracefully (ie: no stack dump)
#     def __init__(self, msg=None):
#         self.msg = msg
# 
#     def __str__(self):
#         return (
#             '\n***** ERROR *****\n'
#             '{0}\n'
#             '\n**Servi Aborting**'.format(self.msg))
# 
# class ForceError(Exception):
#     def __init__(self, msg=None):
#         self.msg = msg
# 
#     def __str__(self):
#         return (
#             '\n***** ERROR *****\n'
#             '{0}\n'
#             'Use -f / --force to override.\n'
#             '\n**Servi Aborting**'.format(self.msg))
# 
# Path: servi/utils.py
# def file_exists(path):
#     return os.path.isfile(path) and os.access(path, os.R_OK)
# 
# def pathfor(fname, source):
#     if source is c.MASTER and fname == c.SERVIFILE_GLOBAL:
#         return c.SERVIFILE_GLOBAL_FULL
#     else:
#         return c.pathfor(fname, source, c.TEMPLATE, c.MASTER, c.TMPL_DIR_SITE,
#                          c.MASTER_DIR)


# Path: servi/template_mgr.py
from datetime import datetime
from logging import debug
from servi.manifest import Manifest
from servi.exceptions import ServiError, ForceError
from servi.utils import file_exists, pathfor
import re
import shutil
import os
import yaml
import servi.config as c

            if fname == c.SERVIFILE_GLOBAL:
                master_fname = c.SERVIFILE_GLOBAL_FULL

            # Deal with .git files - used by included submodules - ignore
            # (template files are just files - too confusing to leave as
            #  submodules!)
            if (os.path.split(fname)[1] == '.git'
                    and os.path.isfile(template_fname)):
                debug('Skipping .git file (submodule marker): {0}'
                      .format(fname))
                continue

            # Always backup (never overwrite) master
            if file_exists(master_fname):
                self.rename_master_file(fname, self.timestamp)
                existing = True
            else:
                existing = False

            # Copy template to master
            destdir = os.path.dirname(master_fname)
            if destdir and not os.path.exists(destdir):
                os.makedirs(destdir)
            shutil.copy2(template_fname, master_fname)
            if existing:
                debug('Updated: {0}'.format(master_fname))
            else:
                debug('Created: {0}'.format(master_fname))

        # Recreate the master manifest

        m = Manifest(c.MASTER)