Source code for bootstrap_py.package

# -*- coding: utf-8 -*-
"""bootstrap_py.package."""
import os
import shutil
import tempfile
from datetime import datetime
from jinja2 import PackageLoader, Environment
from bootstrap_py.classifiers import Classifiers
from bootstrap_py.vcs import VCS
from bootstrap_py.docs import build_sphinx


# pylint: disable=too-few-public-methods
[docs]class PackageData(object): """Package meta data class.""" #: Configured the default "version" of setup.setup(). default_version = '0.1.0' #: Users should rewrite parameters after they generate Python package. warning_message = '##### ToDo: Rewrite me #####' def __init__(self, args): """Initialize Package.""" self.metadata = Classifiers() if hasattr(args, '__dict__'): for name, value in vars(args).items(): self._set_param(name, value) self._check_or_set_default_params() def _set_param(self, name, value): """set name:value property to Package object.""" if name == 'status': setattr(self, name, self.metadata.status().get(value)) elif name == 'license': setattr(self, name, self.metadata.licenses().get(value)) else: setattr(self, name, value) def _check_or_set_default_params(self): """check key and set default vaule when it does not exists.""" if not hasattr(self, 'date'): self._set_param('date', datetime.utcnow().strftime('%Y-%m-%d')) if not hasattr(self, 'version'): self._set_param('version', self.default_version) # pylint: disable=no-member if not hasattr(self, 'description') or self.description is None: getattr(self, '_set_param')('description', self.warning_message)
[docs] def to_dict(self): """Convert the package data to dict.""" return self.__dict__
[docs]class PackageTree(object): """Package directory tree class.""" #: Jinja2 template name template_name = 'bootstrap_py' #: the suffix name of working directory for generating suffix = '-bootstrap-py' #: init filename init = '__init__.py' #: default permission dir_perm = 0o755 #: include directories to packages pkg_dirs = ['{name}', '{name}/tests'] def __init__(self, pkg_data): """Initialize.""" self.cwd = os.getcwd() self.name = pkg_data.name self.outdir = os.path.abspath(pkg_data.outdir) self.tmpdir = tempfile.mkdtemp(suffix=self.suffix) self.templates = Environment(loader=PackageLoader(self.template_name)) self.pkg_data = pkg_data def _modname(self, dir_path): return dir_path.format(name=self.name).replace('/', '.') def _init_py(self, dir_path): return os.path.join(self.tmpdir, dir_path.format(name=self.name), self.init) def _tmpl_path(self, file_path): return os.path.join(self.tmpdir, os.path.splitext(file_path)[0]) def _generate_dirs(self): dirs = [os.path.dirname(tmpl) for tmpl in self.templates.list_templates() if tmpl.find('/') > -1] + self.pkg_dirs for dir_path in dirs: if not os.path.isdir( os.path.join(self.tmpdir, dir_path.format(name=self.name))): os.makedirs(os.path.join(self.tmpdir, dir_path.format(name=self.name)), self.dir_perm) def _generate_docs(self): docs_path = os.path.join(self.tmpdir, 'docs') os.makedirs(docs_path) build_sphinx(self.pkg_data, docs_path) def _list_module_dirs(self): return [dir_path for dir_path in self.pkg_dirs if dir_path.find('{name}') == 0] def _generate_init(self): tmpl = self.templates.get_template('__init__.py.j2') for dir_path in self._list_module_dirs(): if not os.path.isfile(self._init_py(dir_path)): with open(self._init_py(dir_path), 'w') as fobj: # pylint: disable=no-member fobj.write( tmpl.render( module_name=getattr( self, '_modname')(dir_path)) + '\n') def _generate_files(self): for file_path in self.templates.list_templates(): if file_path.endswith('.j2'): if file_path == '__init__.py.j2': self._generate_init() else: tmpl = self.templates.get_template(file_path) with open(self._tmpl_path(file_path), 'w') as fobj: fobj.write( tmpl.render(**self.pkg_data.to_dict()) + '\n') os.chdir(self.tmpdir) os.symlink('../../README.rst', 'docs/source/README.rst') os.chdir(self.cwd)
[docs] def move(self): """Move directory from working directory to output directory.""" if not os.path.isdir(self.outdir): os.makedirs(self.outdir) shutil.move(self.tmpdir, os.path.join(self.outdir, self.name))
[docs] def clean(self): """Clean up working directory.""" shutil.rmtree(self.tmpdir)
[docs] def generate(self): """Generate package directory tree.""" self._generate_docs() self._generate_dirs() self._generate_init() self._generate_files()
[docs] def vcs_init(self): """Initialize VCS repository.""" VCS(os.path.join(self.outdir, self.name), self.pkg_data)