Source code for yamldirs.filemaker

# -*- coding: utf-8 -*-
import textwrap
import warnings
from contextlib import contextmanager
import os
import shutil
import tempfile
import yaml


[docs]class FilemakerBase(object): """Override marked methods to do something useful. Base class serves as a dry-run step generator. """ def __init__(self, root, fdef): self.fdef = yaml.load(fdef) self.goto_directory(root) self._makefiles(self.fdef)
[docs] def goto_directory(self, dirname): # pragma: nocover """Set current directory to ``dirname``. **Must be overridden.** """ print "pushd", dirname
[docs] def makedir(self, dirname, content): # pragma: nocover """Create a new directory named ``dirname``. **Must be overridden.** Overriden method must call self.make_list(content). """ print "mkdir " + dirname print "pushd " + dirname self.make_list(content) print "popd"
[docs] def make_file(self, filename, content): # pragma: nocover """Create a new file with name ``filename`` and content ``content``. **Must be overridden.** """ print "create file: %s %r" % (filename, content)
[docs] def make_empty_file(self, fname): # pragma: nocover """Create an empty file with filename ``fname``. Many backends have special syntax for creating empty files. **Must be overridden.** """ print "touch", fname
[docs] def make_list(self, lst): """Make a list of items. """ for item in lst: self._makefiles(item)
def _make_dict(self, dct): for k, v in dct.items(): if isinstance(v, list): self.makedir(dirname=k, content=v) elif isinstance(v, basestring): self._make_file(filename=k, content=v) else: # pragma: nocover raise ValueError("Unexpected:", k, v) def _make_empty_file(self, fname): # special handling to create empty directories. if fname == 'empty': msg = textwrap.dedent(""" To create an empty directory use an empty list: dirname: [] this syntax (single item list containing `empty`) is deprecated and will be removed in the next major version. """) warnings.warn(msg, DeprecationWarning) if fname != 'empty': self.make_empty_file(fname) def _make_file(self, filename, content=None): if content is None: self._make_empty_file(filename) else: self.make_file(filename, content) def _makefiles(self, f): if isinstance(f, dict): self._make_dict(f) elif isinstance(f, basestring): self._make_file(f) elif isinstance(f, list): self.make_list(f) else: # pragma: nocover raise ValueError("Unknown type:", f)
[docs]class Filemaker(FilemakerBase):
[docs] def goto_directory(self, dirname): """Set current directory to ``dirname``. """ os.chdir(dirname)
[docs] def makedir(self, dirname, content): """Create a new directory named ``dirname``. """ cwd = os.getcwd() os.mkdir(dirname) os.chdir(dirname) self.make_list(content) os.chdir(cwd)
[docs] def make_file(self, filename, content): """Create a new file with name ``filename`` and content ``content``. """ with open(filename, 'w') as fp: fp.write(content)
[docs] def make_empty_file(self, fname): """Create an empty file with filename ``fname``. """ open(fname, 'w').close()
@contextmanager
[docs]def create_files(filedef, cleanup=True): """Contextmanager that creates a directory structure from a yaml descripttion. """ cwd = os.getcwd() tmpdir = tempfile.mkdtemp() try: Filemaker(tmpdir, filedef) if not cleanup: # pragma: nocover pass # print "TMPDIR =", tmpdir yield tmpdir finally: os.chdir(cwd) if cleanup: # pragma: nocover shutil.rmtree(tmpdir, ignore_errors=True)