Source code for microdrop_plugin_template.create_plugin

from argparse import ArgumentParser
import fnmatch
import pkg_resources
import re
import sys
import tempfile as tmp

import git
import path_helpers as ph
import rename_package_files as rp


CRE_PLUGIN_NAME = re.compile(r'^[A-Za-z_][\w_]+$')



[docs]def create_plugin(output_directory, overwrite=False, init_git=True): ''' Parameters ---------- output_directory : str Output directory path. Directory name must be a valid Python module name. overwrite : bool, optional Overwrite existing output directory. Returns ------- path_helpers.path Output directory path. Raises ------ ValueError If `output_directory` name is not a valid Python module name. IOError If `output_directory` exists and `overwrite` is ``False``. ''' output_directory = ph.path(output_directory).realpath() new_name = output_directory.name if not CRE_PLUGIN_NAME.match(new_name): raise ValueError('Invalid plugin name, "{}". Name must be valid ' 'Python module name.'.format(new_name)) # TODO Load ignore list from `.templateignore` ignore_list = ('*.pyc __init__.py create_plugin.py init_hooks.py rename.py' '*bash.exe.stackdump'.split(' ')) def collect_package_resource_files(root=''): files = [] for p_i in pkg_resources.resource_listdir('microdrop_plugin_template', root): path_i = ph.path(root).joinpath(p_i) if pkg_resources.resource_isdir('microdrop_plugin_template', path_i): files.extend(collect_package_resource_files(path_i)) elif pkg_resources.resource_exists('microdrop_plugin_template', path_i): files.append(path_i) return files if output_directory.isdir() and not overwrite: raise IOError('Output directory already exists. Use `overwrite=True` ' 'to overwrite.') working_directory = ph.path(tmp.mkdtemp(prefix='create_plugin-')) try: # 1. Get list of all files in template directory. template_files = collect_package_resource_files() # 2. Filter template files in *ignore* list. filtered_files = [f for f in template_files if not any(fnmatch.fnmatch(f, i) for i in ignore_list)] # 3. Copy filtered files to output directory. for f in filtered_files: resource_filename = \ ph.path(pkg_resources .resource_filename('microdrop_plugin_template', f)) target_filename = working_directory / f target_filename.parent.makedirs_p() resource_filename.copy(target_filename) # 4. Rename `__init__.py.template` to `__init__.py`. source_file = working_directory / '__init__.py.template' target_file = working_directory / '__init__.py' source_file.rename(target_file) # 5. Rename all occurrences of `microdrop-plugin-template` to new name. # - Do not rename contents of `on_plugin_install.py`, since it # contains an import of `microdrop_plugin_template`. rp.rename_package_files(working_directory, 'microdrop-plugin-template', new_name.replace('_', '-'), exclude='*on_plugin_install.py') # 6. Initialize version to 0.1 (a version is required by `release.py`) # - If `git` is available, initialize plugin directory as `git` # repository, and tag contents as `v0.1`. # - Otherwise, create `RELEASE-VERSION` file containing "0.1". # # TODO **N.B.**, File permissions prevent Git repositories from being # removed (at least on Windows). See if this happens on Linux too and # report as bug to [`GitPython`][1] developers if it does. # # [1]: https://github.com/gitpython-developers/GitPython version_initialized = False if init_git: try: files = sorted(list(working_directory.walkfiles())) repo = git.Repo.init(working_directory) repo.index.add(files) repo.index.commit('Initial commit') tag = 'v0.1' repo.git.tag('-a', tag, '-m', 'Initial release') repo.git.clear_cache() print 'Initialized plugin as git repo (tag={})'.format(tag) except Exception, exception: print >> sys.stderr, 'Error initializing git repo.' print >> sys.stderr, exception else: version_initialized = True if not version_initialized: version_path = working_directory.joinpath('RELEASE-VERSION') with version_path.open('w') as version_output: version_output.write('0.1') print 'Wrote version to file: RELEASE-VERSION' # 7. Rename created plugin directory to output path. if output_directory.isdir(): output_directory.rmtree() working_directory.rename(output_directory) return output_directory except Exception, exception: print exception raise finally: # Clean up working directory if necessary. if working_directory.isdir(): working_directory.rmtree()
[docs]def parse_args(args=None): '''Parses arguments, returns ``(options, args)``.''' from mpm.bin import LOG_PARSER if args is None: args = sys.argv parser = ArgumentParser(description='Create a new Microdrop plugin', parents=[LOG_PARSER]) parser.add_argument('-f', '--force-overwrite', action='store_true', help='Force overwrite of existing directory') parser.add_argument('--no-git', action='store_true', help='Disable git repo initialization') parser.add_argument('output_directory', type=ph.path, help='Output ' 'directory. Directory name must be a valid Python ' 'module.') return parser.parse_args()
if __name__ == '__main__': args = parse_args() try: output_directory = create_plugin(args.output_directory, overwrite=args.force_overwrite, init_git=not args.no_git) except IOError, exception: print >> sys.stderr, 'Output directory exists. Use `-f` to overwrite' raise SystemExit(-5) except ValueError, exception: print >> sys.stderr, exception raise SystemExit(-10) else: print 'Wrote plugin to: {}'.format(output_directory)